factor/extra/io/windows/launcher/launcher.factor

155 lines
4.6 KiB
Factor
Raw Normal View History

! Copyright (C) 2007, 2008 Doug Coleman, Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
2007-11-17 23:06:51 -05:00
USING: alien alien.c-types arrays continuations destructors io
2008-02-14 03:20:20 -05:00
io.windows io.windows.nt.pipes libc io.nonblocking
2008-01-25 00:49:03 -05:00
io.streams.duplex windows.types math windows.kernel32 windows
namespaces io.launcher kernel sequences windows.errors assocs
2008-02-18 08:30:16 -05:00
splitting system threads init strings combinators
2008-03-20 16:30:59 -04:00
io.backend accessors concurrency.flags ;
2007-09-20 18:09:08 -04:00
IN: io.windows.launcher
TUPLE: CreateProcess-args
lpApplicationName
lpCommandLine
lpProcessAttributes
lpThreadAttributes
bInheritHandles
dwCreateFlags
lpEnvironment
lpCurrentDirectory
lpStartupInfo
lpProcessInformation
stdout-pipe stdin-pipe ;
: default-CreateProcess-args ( -- obj )
CreateProcess-args construct-empty
0 >>dwCreateFlags
2007-09-20 18:09:08 -04:00
"STARTUPINFO" <c-object>
"STARTUPINFO" heap-size over set-STARTUPINFO-cb >>lpStartupInfo
"PROCESS_INFORMATION" <c-object> >>lpProcessInformation
TRUE >>bInheritHandles ;
2007-09-20 18:09:08 -04:00
: call-CreateProcess ( CreateProcess-args -- )
{
lpApplicationName>>
lpCommandLine>>
lpProcessAttributes>>
lpThreadAttributes>>
bInheritHandles>>
dwCreateFlags>>
lpEnvironment>>
lpCurrentDirectory>>
lpStartupInfo>>
lpProcessInformation>>
2007-09-20 18:09:08 -04:00
} get-slots CreateProcess win32-error=0/f ;
2007-11-24 18:05:34 -05:00
: escape-argument ( str -- newstr )
2008-02-03 15:23:14 -05:00
CHAR: \s over member? [ "\"" swap "\"" 3append ] when ;
2007-11-24 18:05:34 -05:00
2007-11-17 23:06:51 -05:00
: join-arguments ( args -- cmd-line )
2008-02-03 15:23:14 -05:00
[ escape-argument ] map " " join ;
2007-11-17 23:06:51 -05:00
: app-name/cmd-line ( process -- app-name cmd-line )
command>> dup string? [
2007-11-17 23:06:51 -05:00
" " split1
] [
unclip swap join-arguments
] if ;
2007-11-17 23:06:51 -05:00
: cmd-line ( process -- cmd-line )
command>> dup string? [ join-arguments ] unless ;
2007-11-17 23:06:51 -05:00
: fill-lpApplicationName ( process args -- process args )
over app-name/cmd-line
>r >>lpApplicationName
r> >>lpCommandLine ;
2007-11-17 23:06:51 -05:00
: fill-lpCommandLine ( process args -- process args )
over cmd-line >>lpCommandLine ;
: fill-dwCreateFlags ( process args -- process args )
2007-11-17 23:06:51 -05:00
0
pick pass-environment? [ CREATE_UNICODE_ENVIRONMENT bitor ] when
pick detached>> winnt? and [ DETACHED_PROCESS bitor ] when
>>dwCreateFlags ;
: fill-lpEnvironment ( process args -- process args )
over pass-environment? [
[
over get-environment
[ swap % "=" % % "\0" % ] assoc-each
"\0" %
] "" make >c-ushort-array
>>lpEnvironment
] when ;
: fill-startup-info ( process args -- process args )
STARTF_USESTDHANDLES over lpStartupInfo>> set-STARTUPINFO-dwFlags ;
2008-01-25 00:49:03 -05:00
HOOK: fill-redirection io-backend ( process args -- )
2008-01-25 00:49:03 -05:00
M: windows-ce-io fill-redirection 2drop ;
2008-01-25 00:49:03 -05:00
: make-CreateProcess-args ( process -- args )
default-CreateProcess-args
wince? [ fill-lpApplicationName ] [ fill-lpCommandLine ] if
fill-dwCreateFlags
2008-02-14 03:20:20 -05:00
fill-lpEnvironment
fill-startup-info
nip ;
M: windows-io current-process-handle ( -- handle )
GetCurrentProcessId ;
M: windows-io run-process* ( process -- handle )
2007-09-20 18:09:08 -04:00
[
dup make-CreateProcess-args
tuck fill-redirection
dup call-CreateProcess
lpProcessInformation>>
2008-01-25 00:49:03 -05:00
] with-destructors ;
2008-02-03 15:23:14 -05:00
M: windows-io kill-process* ( handle -- )
PROCESS_INFORMATION-hProcess
255 TerminateProcess win32-error=0/f ;
: dispose-process ( process-information -- )
#! From MSDN: "Handles in PROCESS_INFORMATION must be closed
#! with CloseHandle when they are no longer needed."
dup PROCESS_INFORMATION-hProcess [ CloseHandle drop ] when*
PROCESS_INFORMATION-hThread [ CloseHandle drop ] when* ;
: exit-code ( process -- n )
PROCESS_INFORMATION-hProcess
0 <ulong> [ GetExitCodeProcess ] keep *ulong
swap win32-error=0/f ;
: process-exited ( process -- )
dup process-handle exit-code
over process-handle dispose-process
2008-03-06 21:44:52 -05:00
notify-exit ;
: wait-for-processes ( processes -- ? )
keys dup
[ process-handle PROCESS_INFORMATION-hProcess ] map
dup length swap >c-void*-array 0 0
WaitForMultipleObjects
dup HEX: ffffffff = [ win32-error ] when
dup WAIT_TIMEOUT = [ 2drop t ] [ swap nth process-exited f ] if ;
SYMBOL: wait-flag
: wait-loop ( -- )
processes get dup assoc-empty?
[ drop wait-flag get-global lower-flag ]
[ wait-for-processes [ 100 sleep ] when ] if ;
2008-02-21 20:12:55 -05:00
: start-wait-thread ( -- )
<flag> wait-flag set-global
[ wait-loop t ] "Process wait" spawn-server drop ;
2008-02-21 20:12:55 -05:00
M: windows-io register-process
drop wait-flag get-global raise-flag ;
[ start-wait-thread ] "io.windows.launcher" add-init-hook