Merge branch 'local-ocamlbuild' into local-trunk
[SXSI/xpathcomp.git] / utils / alarm.ml
diff --git a/utils/alarm.ml b/utils/alarm.ml
new file mode 100644 (file)
index 0000000..a12936c
--- /dev/null
@@ -0,0 +1,49 @@
+
+let read_procmem pid =
+  let cin = open_in (Printf.sprintf "/proc/%i/status" pid) in
+  let matchline s =
+    try
+      Scanf.sscanf s " VmHWM: %i kB" (fun i -> Some i)
+    with
+      | _ -> None
+  in
+  let rec loop () =
+    match matchline (input_line cin) with
+       Some i -> i
+      | None -> loop ()
+  in
+  let s = try loop() with _ -> -1 in
+  close_in cin;
+  s
+;;
+
+let rec monitor pid timeout mem =
+  let p, s = Unix.waitpid [ Unix.WNOHANG ] pid in
+  if p == 0 then
+    if (Unix.gettimeofday() > timeout || (read_procmem pid) >= mem)
+    then Unix.kill pid Sys.sigkill
+    else
+      let () = Unix.sleep 1 in
+      monitor pid timeout mem
+;;
+
+
+let run args timeout mem =
+  let pid = Unix.fork () in
+  if pid == 0 then
+    Unix.execvp args.(0) args
+  else monitor pid timeout mem
+;;
+
+let () = 
+  if Array.length Sys.argv < 4 then exit 1
+  else
+    try
+      let timeout = Unix.gettimeofday () +. float_of_string Sys.argv.(1) in
+      let mem = int_of_string Sys.argv.(2) in
+      let command = Array.sub Sys.argv 3 ((Array.length Sys.argv) - 3) in
+      run command timeout mem;
+      exit 0
+    with
+       _ -> exit 2
+;;