open Sys;;
open Unix;;

let try_finalize f x finally y =
  let res = try f x with exn -> finally yraise exn in
  finally y;
  res

let mon_execvp com argv =
  let com_argv = Array.concat [ [| com |]; argv ] in
  let old_mask = sigprocmask SIG_BLOCK [ sigchld ] in
  let old_int = signal sigint Signal_ignore in
  let old_quit = signal sigquit Signal_ignore in
  let reset() =
    ignore (signal sigint old_int);
    ignore (signal sigquit old_quit);
    ignore (sigprocmask SIG_SETMASK old_maskin
  let system_call () =
    match fork() with
    | 0 ->
        reset();
        handle_unix_error (fun _ -> execvp com com_argv) ()
    | k ->
        let rec wait() =
          try
            snd (waitpid [] k)
          with Unix_error (EINTR__) -> wait() in
        wait() in
  try_finalize system_call() reset()