2008-01-24 02:27:15 -05:00
|
|
|
! Copyright (C) 2008 Slava Pestov.
|
2007-09-20 18:09:08 -04:00
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2008-02-09 22:34:42 -05:00
|
|
|
USING: io io.backend io.timeouts system kernel namespaces
|
|
|
|
strings hashtables sequences assocs combinators vocabs.loader
|
|
|
|
init threads continuations math ;
|
2007-09-20 18:09:08 -04:00
|
|
|
IN: io.launcher
|
|
|
|
|
2008-01-24 03:19:15 -05:00
|
|
|
! Non-blocking process exit notification facility
|
|
|
|
SYMBOL: processes
|
|
|
|
|
|
|
|
[ H{ } clone processes set-global ] "io.launcher" add-init-hook
|
|
|
|
|
2008-02-09 22:34:42 -05:00
|
|
|
TUPLE: process handle status killed? lapse ;
|
2008-01-24 02:27:15 -05:00
|
|
|
|
2008-01-24 03:19:15 -05:00
|
|
|
HOOK: register-process io-backend ( process -- )
|
|
|
|
|
|
|
|
M: object register-process drop ;
|
|
|
|
|
|
|
|
: <process> ( handle -- process )
|
2008-02-09 22:34:42 -05:00
|
|
|
f f <lapse> process construct-boa
|
2008-01-24 03:19:15 -05:00
|
|
|
V{ } clone over processes get set-at
|
|
|
|
dup register-process ;
|
2008-01-24 02:27:15 -05:00
|
|
|
|
|
|
|
M: process equal? 2drop f ;
|
|
|
|
|
|
|
|
M: process hashcode* process-handle hashcode* ;
|
|
|
|
|
2008-02-09 22:34:42 -05:00
|
|
|
: process-running? ( process -- ? ) process-status not ;
|
|
|
|
|
2007-11-12 23:18:42 -05:00
|
|
|
SYMBOL: +command+
|
|
|
|
SYMBOL: +arguments+
|
|
|
|
SYMBOL: +detached+
|
|
|
|
SYMBOL: +environment+
|
|
|
|
SYMBOL: +environment-mode+
|
2008-01-24 22:45:56 -05:00
|
|
|
SYMBOL: +stdin+
|
|
|
|
SYMBOL: +stdout+
|
|
|
|
SYMBOL: +stderr+
|
|
|
|
SYMBOL: +closed+
|
2008-02-09 22:34:42 -05:00
|
|
|
SYMBOL: +timeout+
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-02-05 18:33:36 -05:00
|
|
|
SYMBOL: +prepend-environment+
|
|
|
|
SYMBOL: +replace-environment+
|
|
|
|
SYMBOL: +append-environment+
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2007-11-12 23:18:42 -05:00
|
|
|
: default-descriptor
|
|
|
|
H{
|
|
|
|
{ +command+ f }
|
|
|
|
{ +arguments+ f }
|
|
|
|
{ +detached+ f }
|
|
|
|
{ +environment+ H{ } }
|
2008-02-05 18:33:36 -05:00
|
|
|
{ +environment-mode+ +append-environment+ }
|
2007-11-12 23:18:42 -05:00
|
|
|
} ;
|
|
|
|
|
|
|
|
: with-descriptor ( desc quot -- )
|
|
|
|
default-descriptor [ >r clone r> bind ] bind ; inline
|
|
|
|
|
2007-11-13 01:10:26 -05:00
|
|
|
: pass-environment? ( -- ? )
|
|
|
|
+environment+ get assoc-empty? not
|
2008-02-05 18:33:36 -05:00
|
|
|
+environment-mode+ get +replace-environment+ eq? or ;
|
2007-11-13 01:10:26 -05:00
|
|
|
|
|
|
|
: get-environment ( -- env )
|
|
|
|
+environment+ get
|
|
|
|
+environment-mode+ get {
|
2008-02-05 18:33:36 -05:00
|
|
|
{ +prepend-environment+ [ os-envs union ] }
|
|
|
|
{ +append-environment+ [ os-envs swap union ] }
|
|
|
|
{ +replace-environment+ [ ] }
|
2007-11-13 01:10:26 -05:00
|
|
|
} case ;
|
|
|
|
|
2008-01-31 00:16:20 -05:00
|
|
|
GENERIC: >descriptor ( desc -- desc )
|
2007-11-12 23:18:42 -05:00
|
|
|
|
|
|
|
M: string >descriptor +command+ associate ;
|
|
|
|
M: sequence >descriptor +arguments+ associate ;
|
2008-01-25 01:21:49 -05:00
|
|
|
M: assoc >descriptor >hashtable ;
|
2007-11-12 23:18:42 -05:00
|
|
|
|
2008-01-24 02:27:15 -05:00
|
|
|
HOOK: run-process* io-backend ( desc -- handle )
|
2007-11-12 23:18:42 -05:00
|
|
|
|
2008-01-24 02:27:15 -05:00
|
|
|
: wait-for-process ( process -- status )
|
2008-02-09 22:34:42 -05:00
|
|
|
[
|
|
|
|
dup process-handle
|
|
|
|
[ dup [ processes get at push stop ] curry callcc0 ] when
|
|
|
|
dup process-killed?
|
|
|
|
[ "Process was killed" throw ] [ process-status ] if
|
|
|
|
] with-timeout ;
|
2007-11-12 23:18:42 -05:00
|
|
|
|
2008-01-31 00:16:20 -05:00
|
|
|
: run-process ( desc -- process )
|
2008-01-24 02:27:15 -05:00
|
|
|
>descriptor
|
|
|
|
dup run-process*
|
2008-02-09 22:34:42 -05:00
|
|
|
+timeout+ pick at [ over set-timeout ] when*
|
2008-01-24 02:27:15 -05:00
|
|
|
+detached+ rot at [ dup wait-for-process drop ] unless ;
|
|
|
|
|
2008-01-31 00:16:20 -05:00
|
|
|
: run-detached ( desc -- process )
|
2008-01-24 02:27:15 -05:00
|
|
|
>descriptor H{ { +detached+ t } } union run-process ;
|
|
|
|
|
2008-02-08 22:15:29 -05:00
|
|
|
TUPLE: process-failed code ;
|
|
|
|
|
|
|
|
: process-failed ( code -- * )
|
|
|
|
process-failed construct-boa throw ;
|
|
|
|
|
|
|
|
: try-process ( desc -- )
|
|
|
|
run-process wait-for-process dup zero?
|
|
|
|
[ drop ] [ process-failed ] if ;
|
|
|
|
|
2008-02-03 15:23:14 -05:00
|
|
|
HOOK: kill-process* io-backend ( handle -- )
|
|
|
|
|
|
|
|
: kill-process ( process -- )
|
2008-02-09 22:34:42 -05:00
|
|
|
t over set-process-killed?
|
2008-02-03 15:23:14 -05:00
|
|
|
process-handle [ kill-process* ] when* ;
|
|
|
|
|
2008-02-09 22:56:50 -05:00
|
|
|
M: process get-lapse process-lapse ;
|
|
|
|
|
2008-02-09 22:34:42 -05:00
|
|
|
M: process timed-out kill-process ;
|
|
|
|
|
2008-01-24 02:27:15 -05:00
|
|
|
HOOK: process-stream* io-backend ( desc -- stream process )
|
|
|
|
|
|
|
|
TUPLE: process-stream process ;
|
2007-11-12 23:18:42 -05:00
|
|
|
|
2008-01-31 00:16:20 -05:00
|
|
|
: <process-stream> ( desc -- stream )
|
2008-01-24 02:27:15 -05:00
|
|
|
>descriptor process-stream*
|
|
|
|
{ set-delegate set-process-stream-process }
|
|
|
|
process-stream construct ;
|
|
|
|
|
2008-02-04 20:38:19 -05:00
|
|
|
: with-process-stream ( desc quot -- status )
|
2008-01-24 02:27:15 -05:00
|
|
|
swap <process-stream>
|
|
|
|
[ swap with-stream ] keep
|
2008-02-04 20:38:19 -05:00
|
|
|
process-stream-process wait-for-process ; inline
|
2008-01-24 03:19:15 -05:00
|
|
|
|
|
|
|
: notify-exit ( status process -- )
|
|
|
|
[ set-process-status ] keep
|
|
|
|
[ processes get delete-at* drop [ schedule-thread ] each ] keep
|
|
|
|
f swap set-process-handle ;
|