src/Pure/General/system_process.ML
author wenzelm
Sat, 16 Feb 2008 16:43:54 +0100
changeset 26078 4fc74eb2842b
child 26085 4ce22e7a81bd
permissions -rw-r--r--
System shell processes, with static input/output and propagation of interrupts.

(*  Title:      Pure/General/system_process.ML
    ID:         $Id$
    Author:     Makarius

System shell processes, with static input/output and propagation of interrupts.
*)

signature SYSTEM_PROCESS =
sig
  val system_out: string -> string * int
  val system: string -> int
end;

structure SystemProcess: SYSTEM_PROCESS =
struct

fun system_out cmdline = uninterruptible (fn restore_attributes => fn () =>
  let
    val _ = Secure.deny_secure "Cannot execute shell commands in secure mode";

    val proc = Unix.execute (cmdline, []);
    val (proc_stdout, proc_stdin) = Unix.streamsOf proc;

    fun read buf =
      (case Exn.capture (restore_attributes TextIO.input) proc_stdout of
        Exn.Exn Interrupt => (Unix.kill (proc, Posix.Signal.int); read buf)
      | Exn.Exn _ => buf
      | Exn.Result "" => buf
      | Exn.Result txt => read (Buffer.add txt buf));
    val output = read Buffer.empty;
    val status = Unix.reap proc;
    val rc = Unix.fromStatus status;
  in
    tracing (PolyML.makestring (Unix.fromStatus status));
    if rc = Unix.W_SIGNALED Posix.Signal.int orelse rc = Unix.W_EXITSTATUS 0wx82
    then raise Interrupt
    else (Buffer.content output, if OS.Process.isSuccess status then 0 else 1)
  end) ();

fun system cmdline =
  let val (output, status) = system_out cmdline in writeln output; status end;

end;