165 lines
5.0 KiB
Factor
Executable File
165 lines
5.0 KiB
Factor
Executable File
! Copyright (C) 2007, 2008 Doug Coleman, Slava Pestov.
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
USING: alien alien.c-types arrays continuations io
|
|
io.backend.windows io.pipes.windows.nt io.pathnames libc io.ports
|
|
windows.types math windows.kernel32
|
|
namespaces make io.launcher kernel sequences windows.errors
|
|
splitting system threads init strings combinators
|
|
io.backend accessors concurrency.flags io.files assocs
|
|
io.files.private windows destructors specialized-arrays.ushort
|
|
specialized-arrays.alien ;
|
|
IN: io.launcher.windows
|
|
|
|
TUPLE: CreateProcess-args
|
|
lpApplicationName
|
|
lpCommandLine
|
|
lpProcessAttributes
|
|
lpThreadAttributes
|
|
bInheritHandles
|
|
dwCreateFlags
|
|
lpEnvironment
|
|
lpCurrentDirectory
|
|
lpStartupInfo
|
|
lpProcessInformation ;
|
|
|
|
: default-CreateProcess-args ( -- obj )
|
|
CreateProcess-args new
|
|
"STARTUPINFO" <c-object>
|
|
"STARTUPINFO" heap-size over set-STARTUPINFO-cb >>lpStartupInfo
|
|
"PROCESS_INFORMATION" <c-object> >>lpProcessInformation
|
|
TRUE >>bInheritHandles
|
|
0 >>dwCreateFlags ;
|
|
|
|
: call-CreateProcess ( CreateProcess-args -- )
|
|
{
|
|
[ lpApplicationName>> ]
|
|
[ lpCommandLine>> ]
|
|
[ lpProcessAttributes>> ]
|
|
[ lpThreadAttributes>> ]
|
|
[ bInheritHandles>> ]
|
|
[ dwCreateFlags>> ]
|
|
[ lpEnvironment>> ]
|
|
[ lpCurrentDirectory>> ]
|
|
[ lpStartupInfo>> ]
|
|
[ lpProcessInformation>> ]
|
|
} cleave
|
|
CreateProcess win32-error=0/f ;
|
|
|
|
: count-trailing-backslashes ( str n -- str n )
|
|
[ "\\" ?tail ] dip swap [
|
|
1+ count-trailing-backslashes
|
|
] when ;
|
|
|
|
: fix-trailing-backslashes ( str -- str' )
|
|
0 count-trailing-backslashes
|
|
2 * CHAR: \\ <repetition> append ;
|
|
|
|
: escape-argument ( str -- newstr )
|
|
CHAR: \s over member? [
|
|
fix-trailing-backslashes "\"" dup surround
|
|
] when ;
|
|
|
|
: join-arguments ( args -- cmd-line )
|
|
[ escape-argument ] map " " join ;
|
|
|
|
: lookup-priority ( process -- n )
|
|
priority>> {
|
|
{ +lowest-priority+ [ IDLE_PRIORITY_CLASS ] }
|
|
{ +low-priority+ [ BELOW_NORMAL_PRIORITY_CLASS ] }
|
|
{ +normal-priority+ [ NORMAL_PRIORITY_CLASS ] }
|
|
{ +high-priority+ [ ABOVE_NORMAL_PRIORITY_CLASS ] }
|
|
{ +highest-priority+ [ HIGH_PRIORITY_CLASS ] }
|
|
{ +realtime-priority+ [ REALTIME_PRIORITY_CLASS ] }
|
|
[ drop f ]
|
|
} case ;
|
|
|
|
: app-name/cmd-line ( process -- app-name cmd-line )
|
|
command>> dup string? [
|
|
" " split1
|
|
] [
|
|
unclip swap join-arguments
|
|
] if ;
|
|
|
|
: cmd-line ( process -- cmd-line )
|
|
command>> dup string? [ join-arguments ] unless ;
|
|
|
|
: fill-lpApplicationName ( process args -- process args )
|
|
over app-name/cmd-line
|
|
[ >>lpApplicationName ] [ >>lpCommandLine ] bi* ;
|
|
|
|
: fill-lpCommandLine ( process args -- process args )
|
|
over cmd-line >>lpCommandLine ;
|
|
|
|
: fill-dwCreateFlags ( process args -- process args )
|
|
0
|
|
pick pass-environment? [ CREATE_UNICODE_ENVIRONMENT bitor ] when
|
|
pick detached>> os winnt? and [ DETACHED_PROCESS bitor ] when
|
|
pick lookup-priority [ bitor ] when*
|
|
>>dwCreateFlags ;
|
|
|
|
: fill-lpEnvironment ( process args -- process args )
|
|
over pass-environment? [
|
|
[
|
|
over get-environment
|
|
[ swap % "=" % % "\0" % ] assoc-each
|
|
"\0" %
|
|
] ushort-array{ } make underlying>>
|
|
>>lpEnvironment
|
|
] when ;
|
|
|
|
: fill-startup-info ( process args -- process args )
|
|
STARTF_USESTDHANDLES over lpStartupInfo>> set-STARTUPINFO-dwFlags ;
|
|
|
|
HOOK: fill-redirection io-backend ( process args -- )
|
|
|
|
M: wince fill-redirection 2drop ;
|
|
|
|
: make-CreateProcess-args ( process -- args )
|
|
default-CreateProcess-args
|
|
os wince? [ fill-lpApplicationName ] [ fill-lpCommandLine ] if
|
|
fill-dwCreateFlags
|
|
fill-lpEnvironment
|
|
fill-startup-info
|
|
nip ;
|
|
|
|
M: windows current-process-handle ( -- handle )
|
|
GetCurrentProcessId ;
|
|
|
|
M: windows run-process* ( process -- handle )
|
|
[
|
|
current-directory get (normalize-path) cd
|
|
|
|
dup make-CreateProcess-args
|
|
tuck fill-redirection
|
|
dup call-CreateProcess
|
|
lpProcessInformation>>
|
|
] with-destructors ;
|
|
|
|
M: windows 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 handle>> exit-code
|
|
over handle>> dispose-process
|
|
notify-exit ;
|
|
|
|
M: windows wait-for-processes ( -- ? )
|
|
processes get keys dup
|
|
[ handle>> PROCESS_INFORMATION-hProcess ] void*-array{ } map-as
|
|
[ length ] [ underlying>> ] bi 0 0
|
|
WaitForMultipleObjects
|
|
dup HEX: ffffffff = [ win32-error ] when
|
|
dup WAIT_TIMEOUT = [ 2drop t ] [ swap nth process-exited f ] if ;
|