factor/extra/io/unix/launcher/launcher.factor

98 lines
2.7 KiB
Factor
Raw Normal View History

! Copyright (C) 2007, 2008 Slava Pestov.
2007-11-12 23:18:42 -05:00
! See http://factorcode.org/license.txt for BSD license.
USING: io io.backend io.launcher io.unix.backend io.unix.files
io.nonblocking sequences kernel namespaces math system
2008-03-03 17:45:18 -05:00
alien.c-types debugger continuations arrays assocs combinators
unix.process strings threads unix ;
IN: io.unix.launcher
2007-09-20 18:09:08 -04:00
! Search unix first
USE: unix
2007-11-12 23:18:42 -05:00
: get-arguments ( -- seq )
+command+ get [ tokenize-command ] [ +arguments+ get ] if* ;
2007-11-12 23:18:42 -05:00
2007-11-24 18:32:19 -05:00
: assoc>env ( assoc -- env )
[ "=" swap 3append ] { } assoc>map ;
2007-11-12 23:18:42 -05:00
: (redirect) ( path mode fd -- )
2008-01-24 22:48:28 -05:00
>r file-mode open dup io-error dup
r> dup2 io-error close ;
2008-01-24 22:48:28 -05:00
: redirect ( obj mode fd -- )
{
{ [ pick not ] [ 2nip F_SETFL 0 fcntl io-error ] }
{ [ pick string? ] [ (redirect) ] }
} cond ;
2008-02-14 03:20:20 -05:00
: ?closed dup +closed+ eq? [ drop "/dev/null" ] when ;
: setup-redirection ( -- )
2008-02-14 03:20:20 -05:00
+stdin+ get ?closed read-flags 0 redirect
+stdout+ get ?closed write-flags 1 redirect
2008-02-03 16:55:59 -05:00
+stderr+ get dup +stdout+ eq?
2008-02-14 03:20:20 -05:00
[ drop 1 2 dup2 io-error ] [ ?closed write-flags 2 redirect ] if ;
: spawn-process ( -- )
2007-11-12 23:18:42 -05:00
[
setup-redirection
get-arguments
pass-environment?
[ get-environment assoc>env exec-args-with-env ]
[ exec-args-with-path ] if
io-error
2007-11-12 23:18:42 -05:00
] [ error. :c flush ] recover 1 exit ;
2007-09-20 18:09:08 -04:00
M: unix-io current-process-handle ( -- handle ) getpid ;
M: unix-io run-process* ( desc -- pid )
2007-11-12 23:18:42 -05:00
[
[ spawn-process ] [ ] with-fork <process>
2007-11-12 23:18:42 -05:00
] with-descriptor ;
2007-09-20 18:09:08 -04:00
2008-02-03 15:23:14 -05:00
M: unix-io kill-process* ( pid -- )
SIGTERM kill io-error ;
2007-09-20 18:09:08 -04:00
: open-pipe ( -- pair )
2 "int" <c-array> dup pipe zero?
[ 2 c-int-array> ] [ drop f ] if ;
: setup-stdio-pipe ( stdin stdout -- )
2dup first close second close
>r first 0 dup2 drop r> second 1 dup2 drop ;
2007-11-12 23:18:42 -05:00
: spawn-process-stream ( -- in out pid )
2007-09-20 18:09:08 -04:00
open-pipe open-pipe [
setup-stdio-pipe
spawn-process
2007-09-20 18:09:08 -04:00
] [
2007-11-15 18:06:40 -05:00
-rot 2dup second close first close
] with-fork first swap second rot <process> ;
M: unix-io process-stream*
[
spawn-process-stream >r handle>duplex-stream r>
] with-descriptor ;
2007-09-20 18:09:08 -04:00
: find-process ( handle -- process )
2008-01-24 23:41:55 -05:00
processes get swap [ nip swap process-handle = ] curry
assoc-find 2drop ;
2007-09-20 18:09:08 -04:00
! Inefficient process wait polling, used on Linux and Solaris.
! On BSD and Mac OS X, we use kqueue() which scales better.
: wait-for-processes ( -- ? )
-1 0 <int> tuck WNOHANG waitpid
2008-01-24 20:10:17 -05:00
dup 0 <= [
2drop t
] [
find-process dup [
2008-02-04 21:10:00 -05:00
>r *int WEXITSTATUS r> notify-exit f
] [
2drop f
] if
] if ;
2007-09-20 18:09:08 -04:00
: start-wait-thread ( -- )
2008-02-18 08:30:16 -05:00
[ wait-for-processes [ 250 sleep ] when t ]
"Process reaper" spawn-server drop ;