1 ! Copyright (C) 2007, 2010 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors alien.c-types alien.data assocs combinators
4 continuations environment io.backend io.backend.unix
5 io.files.private io.files.unix io.launcher io.launcher.private
6 io.pathnames io.ports kernel libc math namespaces sequences
7 simple-tokenizer strings system unix unix.ffi unix.process ;
10 : get-arguments ( process -- seq )
11 command>> dup string? [ tokenize ] when ;
13 : assoc>env ( assoc -- env )
14 [ "=" glue ] { } assoc>map ;
16 : setup-process-group ( process -- process )
19 { +new-group+ [ 0 0 setpgid io-error ] }
20 { +new-session+ [ setsid io-error ] }
23 : setup-priority ( process -- process )
26 { +lowest-priority+ [ 20 ] }
27 { +low-priority+ [ 10 ] }
28 { +normal-priority+ [ 0 ] }
29 { +high-priority+ [ -10 ] }
30 { +highest-priority+ [ -20 ] }
31 { +realtime-priority+ [ -20 ] }
36 [ F_SETFL 0 fcntl io-error ] [ F_SETFD 0 fcntl io-error ] bi ;
38 : redirect-fd ( oldfd fd -- )
39 2dup = [ 2drop ] [ dup2 io-error ] if ;
41 : redirect-file ( obj mode fd -- )
42 [ [ normalize-path ] dip file-mode open-file ] dip redirect-fd ;
44 : redirect-file-append ( obj mode fd -- )
45 [ drop path>> normalize-path open-append ] dip redirect-fd ;
47 : redirect-closed ( obj mode fd -- )
48 [ drop "/dev/null" ] 2dip redirect-file ;
50 : redirect ( obj mode fd -- )
52 { [ pick not ] [ 3drop ] }
53 { [ pick string? ] [ redirect-file ] }
54 { [ pick appender? ] [ redirect-file-append ] }
55 { [ pick +closed+ eq? ] [ redirect-closed ] }
56 { [ pick fd? ] [ [ drop fd>> dup reset-fd ] dip redirect-fd ] }
57 [ [ underlying-handle ] 2dip redirect ]
60 : ?closed ( obj -- obj' )
61 dup +closed+ eq? [ drop "/dev/null" ] when ;
63 : setup-redirection ( process -- process )
64 dup stdin>> ?closed read-flags 0 redirect
65 dup stdout>> ?closed write-flags 1 redirect
66 dup stderr>> dup +stdout+ eq? [
67 drop 1 2 dup2 io-error
69 ?closed write-flags 2 redirect
72 : setup-environment ( process -- process )
73 dup pass-environment? [
74 dup get-environment set-os-envs
77 ! Ignored signals are not reset to the default handler.
78 : reset-ignored-signals ( process -- process )
79 SIGPIPE SIG_DFL signal drop ;
81 : spawn-process ( process -- * )
82 [ reset-ignored-signals ] [ 2drop 248 _exit ] recover
83 [ setup-process-group ] [ 2drop 249 _exit ] recover
84 [ setup-priority ] [ 2drop 250 _exit ] recover
85 [ setup-redirection ] [ 2drop 251 _exit ] recover
86 [ "." absolute-path cd ] [ 2drop 252 _exit ] recover
87 [ setup-environment ] [ 2drop 253 _exit ] recover
88 [ get-arguments exec-args-with-path ] [ 2drop 254 _exit ] recover
92 M: unix (current-process) ( -- handle ) getpid ;
94 M: unix (run-process) ( process -- pid )
95 [ spawn-process ] curry [ ] with-fork ;
97 M: unix (kill-process) ( process -- )
98 [ handle>> SIGTERM ] [ group>> ] bi {
99 { +same-group+ [ kill ] }
100 { +new-group+ [ killpg ] }
101 { +new-session+ [ killpg ] }
104 : find-process ( handle -- process )
105 processes get swap [ nip swap handle>> = ] curry
110 : code>status ( code -- obj )
111 dup WIFSIGNALED [ WTERMSIG signal boa ] [ WEXITSTATUS ] if ;
113 M: unix (wait-for-processes) ( -- ? )
114 { int } [ -1 swap WNOHANG waitpid ] with-out-parameters
119 [ swap code>status notify-exit f ] [ 2drop f ] if