factor/basis/io/launcher/unix/unix.factor

121 lines
3.7 KiB
Factor
Raw Normal View History

! Copyright (C) 2007, 2010 Slava Pestov.
2007-11-12 23:18:42 -05:00
! See http://factorcode.org/license.txt for BSD license.
USING: accessors alien.c-types alien.data assocs combinators
continuations environment io.backend io.backend.unix
io.files.private io.files.unix io.launcher io.launcher.private
io.pathnames io.ports kernel libc math namespaces sequences
simple-tokenizer strings system unix unix.ffi unix.process ;
IN: io.launcher.unix
2008-03-06 21:44:52 -05:00
: get-arguments ( process -- seq )
command>> dup string? [ tokenize ] when ;
2007-11-24 18:32:19 -05:00
: assoc>env ( assoc -- env )
2008-12-03 20:10:41 -05:00
[ "=" glue ] { } assoc>map ;
: setup-process-group ( process -- process )
dup group>> {
{ +same-group+ [ ] }
{ +new-group+ [ 0 0 setpgid io-error ] }
{ +new-session+ [ setsid io-error ] }
} case ;
2008-03-24 19:02:39 -04:00
: setup-priority ( process -- process )
dup priority>> [
{
{ +lowest-priority+ [ 20 ] }
{ +low-priority+ [ 10 ] }
{ +normal-priority+ [ 0 ] }
{ +high-priority+ [ -10 ] }
{ +highest-priority+ [ -20 ] }
{ +realtime-priority+ [ -20 ] }
} case set-priority
2008-03-24 19:02:39 -04:00
] when* ;
2008-07-03 18:44:44 -04:00
: reset-fd ( fd -- )
[ F_SETFL 0 fcntl io-error ] [ F_SETFD 0 fcntl io-error ] bi ;
2008-03-04 16:07:57 -05:00
: redirect-fd ( oldfd fd -- )
2008-06-18 02:40:48 -04:00
2dup = [ 2drop ] [ dup2 io-error ] if ;
2008-03-04 16:07:57 -05:00
: redirect-file ( obj mode fd -- )
[ [ normalize-path ] dip file-mode open-file ] dip redirect-fd ;
2007-11-12 23:18:42 -05:00
2008-05-05 20:12:22 -04:00
: redirect-file-append ( obj mode fd -- )
[ drop path>> normalize-path open-append ] dip redirect-fd ;
2008-05-05 20:12:22 -04:00
2008-03-04 16:07:57 -05:00
: redirect-closed ( obj mode fd -- )
[ drop "/dev/null" ] 2dip redirect-file ;
2007-11-12 23:18:42 -05:00
: redirect ( obj mode fd -- )
{
{ [ pick not ] [ 3drop ] }
2008-03-04 16:07:57 -05:00
{ [ pick string? ] [ redirect-file ] }
2008-05-05 20:12:22 -04:00
{ [ pick appender? ] [ redirect-file-append ] }
2008-03-04 16:07:57 -05:00
{ [ pick +closed+ eq? ] [ redirect-closed ] }
{ [ pick fd? ] [ [ drop fd>> dup reset-fd ] dip redirect-fd ] }
[ [ underlying-handle ] 2dip redirect ]
} cond ;
2008-06-08 16:32:55 -04:00
: ?closed ( obj -- obj' )
dup +closed+ eq? [ drop "/dev/null" ] when ;
2008-02-14 03:20:20 -05:00
2008-03-06 21:44:52 -05:00
: setup-redirection ( process -- process )
dup stdin>> ?closed read-flags 0 redirect
dup stdout>> ?closed write-flags 1 redirect
2008-03-24 19:02:39 -04:00
dup stderr>> dup +stdout+ eq? [
drop 1 2 dup2 io-error
] [
?closed write-flags 2 redirect
] if ;
2008-04-06 00:31:41 -04:00
: setup-environment ( process -- process )
dup pass-environment? [
dup get-environment set-os-envs
] when ;
! Ignored signals are not reset to the default handler.
: reset-ignored-signals ( process -- process )
SIGPIPE SIG_DFL signal drop ;
2008-03-06 21:44:52 -05:00
: spawn-process ( process -- * )
[ reset-ignored-signals ] [ 2drop 248 _exit ] recover
[ setup-process-group ] [ 2drop 249 _exit ] recover
[ setup-priority ] [ 2drop 250 _exit ] recover
[ setup-redirection ] [ 2drop 251 _exit ] recover
[ current-directory get cd ] [ 2drop 252 _exit ] recover
[ setup-environment ] [ 2drop 253 _exit ] recover
[ get-arguments exec-args-with-path ] [ 2drop 254 _exit ] recover
255 _exit
f throw ;
2007-09-20 18:09:08 -04:00
M: unix (current-process) ( -- handle ) getpid ;
M: unix (run-process) ( process -- pid )
2008-03-06 21:44:52 -05:00
[ spawn-process ] curry [ ] with-fork ;
2007-09-20 18:09:08 -04:00
M: unix (kill-process) ( process -- )
[ handle>> SIGTERM ] [ group>> ] bi {
{ +same-group+ [ kill ] }
{ +new-group+ [ killpg ] }
{ +new-session+ [ killpg ] }
} case io-error ;
2008-02-03 15:23:14 -05:00
: find-process ( handle -- process )
2008-03-06 21:44:52 -05:00
processes get swap [ nip swap handle>> = ] curry
2008-01-24 23:41:55 -05:00
assoc-find 2drop ;
2007-09-20 18:09:08 -04:00
2008-12-10 18:30:07 -05:00
TUPLE: signal n ;
: code>status ( code -- obj )
dup WIFSIGNALED [ WTERMSIG signal boa ] [ WEXITSTATUS ] if ;
2008-12-10 18:30:07 -05:00
M: unix (wait-for-processes) ( -- ? )
{ int } [ -1 swap WNOHANG waitpid ] with-out-parameters
swap dup 0 <= [
2drop t
] [
2008-12-10 18:30:07 -05:00
find-process dup
[ swap code>status notify-exit f ] [ 2drop f ] if
] if ;