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

102 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.nonblocking
sequences kernel namespaces math system alien.c-types debugger
continuations arrays assocs combinators unix.process
2007-11-24 18:32:19 -05:00
parser-combinators memoize promises strings ;
IN: io.unix.launcher
2007-09-20 18:09:08 -04:00
! Search unix first
USE: unix
! Our command line parser. Supported syntax:
! foo bar baz -- simple tokens
! foo\ bar -- escaping the space
! 'foo bar' -- quotation
! "foo bar" -- quotation
LAZY: 'escaped-char' "\\" token any-char-parser &> ;
LAZY: 'quoted-char' ( delimiter -- parser' )
'escaped-char'
swap [ member? not ] curry satisfy
<|> ; inline
LAZY: 'quoted' ( delimiter -- parser )
dup 'quoted-char' <!*> swap dup surrounded-by ;
LAZY: 'unquoted' ( -- parser ) " '\"" 'quoted-char' <!+> ;
LAZY: 'argument' ( -- parser )
"\"" 'quoted' "'" 'quoted' 'unquoted' <|> <|>
[ >string ] <@ ;
2007-11-24 20:27:09 -05:00
MEMO: 'arguments' ( -- parser )
'argument' " " token <!+> nonempty-list-of ;
: tokenize-command ( command -- arguments )
'arguments' just parse-1 ;
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
: spawn-process ( -- )
2007-11-12 23:18:42 -05:00
[
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 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
: 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 )
f process construct-boa processes get at ;
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 [
>r *uint r> notify-exit f
] [
2drop f
] if
] if ;
2007-09-20 18:09:08 -04:00
: wait-loop ( -- )
wait-for-processes [ 250 sleep ] when wait-loop ;
2007-09-20 18:09:08 -04:00
: start-wait-thread ( -- )
[ wait-loop ] in-thread ;