[MLton-commit] r7158
Matthew Fluet
fluet at mlton.org
Wed Jun 17 10:05:47 PDT 2009
Different implementations of MLton.Process.{reap,kill} for fork vs. create.
----------------------------------------------------------------------
U mlton/trunk/basis-library/mlton/process.sml
U mlton/trunk/basis-library/posix/process.sig
----------------------------------------------------------------------
Modified: mlton/trunk/basis-library/mlton/process.sml
===================================================================
--- mlton/trunk/basis-library/mlton/process.sml 2009-06-17 16:48:55 UTC (rev 7157)
+++ mlton/trunk/basis-library/mlton/process.sml 2009-06-17 17:05:47 UTC (rev 7158)
@@ -174,7 +174,11 @@
end
datatype ('stdin, 'stdout, 'stderr) t =
- T of {pid: Process.pid,
+ T of {pid: Process.pid, (* if useWindowsProcess,
+ * then this is a Windows process handle
+ * and can't be passed to
+ * Posix.Process.* functions.
+ *)
status: Posix.Process.exit_status option ref,
stderr: ('stderr, input) Child.t,
stdin: ('stdin, output) Child.t,
@@ -197,39 +201,74 @@
DynamicWind.wind (fn () => f x, fn () => Mask.unblock Mask.all)
end
- fun reap (T {pid, status, stderr, stdin, stdout}) =
- case !status of
- NONE =>
- let
- val _ = Child.close (!stdin, !stdout, !stderr)
- (* protect is probably too much; typically, one
- * would only mask SIGINT, SIGQUIT and SIGHUP
- *)
- val (_, st) =
- protect (Process.waitpid, (Process.W_CHILD pid, []))
- val () = status := SOME st
- in
- st
- end
- | SOME status => status
+ local
+ fun reap reapFn (T {pid, status, stderr, stdin, stdout, ...}) =
+ case !status of
+ NONE =>
+ let
+ val _ = Child.close (!stdin, !stdout, !stderr)
+ val st = reapFn pid
+ in
+ status := SOME st
+ ; st
+ end
+ | SOME st => st
+ in
+ fun reapForFork p =
+ reap (fn pid =>
+ let
+ (* protect is probably too much; typically, one
+ * would only mask SIGINT, SIGQUIT and SIGHUP.
+ *)
+ val (_, st) =
+ protect (Process.waitpid, (Process.W_CHILD pid, []))
+ in
+ st
+ end)
+ p
+ fun reapForCreate p =
+ reap (fn pid =>
+ let
+ val pid' = PId.toRep pid
+ val status' = ref (C_Status.fromInt 0)
+ val () =
+ SysCall.simple
+ (fn () =>
+ PrimitiveFFI.Windows.Process.getexitcode
+ (pid', status'))
+ in
+ Process.fromStatus' (!status')
+ end)
+ p
+ end
+ val reap = fn p =>
+ (if useWindowsProcess then reapForCreate else reapForFork) p
- fun kill (p as T {pid, status, ...}, signal) =
- case !status of
- NONE =>
- let
- val pid' = PId.toRep pid
- val signal' = Signal.toRep signal
- val () =
- if useWindowsProcess
- then
- SysCall.simple
- (fn () =>
- PrimitiveFFI.Windows.Process.terminate (pid', signal'))
- else Process.kill (Process.K_PROC pid, signal)
- in
- ignore (reap p)
- end
- | SOME _ => ()
+ local
+ fun kill killFn (p as T {pid, status, ...}, signal) =
+ case !status of
+ NONE =>
+ let
+ val () = killFn (pid, signal)
+ in
+ ignore (reap p)
+ end
+ | SOME _ => ()
+ in
+ fun killForFork p =
+ kill (fn (pid, signal) =>
+ Process.kill (Process.K_PROC pid, signal))
+ p
+ fun killForCreate p =
+ kill (fn (pid, signal) =>
+ SysCall.simple
+ (fn () =>
+ PrimitiveFFI.Windows.Process.terminate
+ (PId.toRep pid, Signal.toRep signal)))
+ p
+ end
+ val kill = fn (p, signal) =>
+ (if useWindowsProcess then killForCreate else killForFork) (p, signal)
fun launchWithFork (path, args, env, stdin, stdout, stderr) =
case protect (Process.fork, ()) of
Modified: mlton/trunk/basis-library/posix/process.sig
===================================================================
--- mlton/trunk/basis-library/posix/process.sig 2009-06-17 16:48:55 UTC (rev 7157)
+++ mlton/trunk/basis-library/posix/process.sig 2009-06-17 17:05:47 UTC (rev 7158)
@@ -46,4 +46,5 @@
signature POSIX_PROCESS_EXTRA =
sig
include POSIX_PROCESS
+ val fromStatus': C_Status.t -> exit_status
end
More information about the MLton-commit
mailing list