putenv "JOBNAME" job.job_name;
(* Create a temporary file containing the shell script fragment. *)
- let script = dir // "script" in
+ let script = dir // "script.sh" in
let chan = open_out script in
fprintf chan "set -e\n"; (* So that jobs exit on error. *)
output_string chan job.job_script.sh_script;
let shell = try getenv "SHELL" with Not_found -> "/bin/sh" in
+ (* Set output to file. *)
+ let output = dir // "output.txt" in
+ let fd = openfile output [O_WRONLY; O_CREAT; O_TRUNC; O_NOCTTY] 0o600 in
+ dup2 fd stdout;
+ dup2 fd stderr;
+ close fd;
+
(* Execute the shell script. *)
(try execvp shell [| shell; "-c"; script |];
with Unix_error (err, fn, _) ->
(* Look up the PID in the running jobs map. *)
let job, dir = IntMap.find pid !running in
running := IntMap.remove pid !running;
- cleanup_job job dir
+ cleanup_job job dir status
)
with Unix_error _ | Not_found -> ()
-and cleanup_job job dir =
+and cleanup_job job dir status =
+ (* If there is a cleanup function, run it. *)
+ (match job.job_cleanup with
+ | None -> ()
+ | Some cleanup ->
+ let code =
+ match status with
+ | WEXITED c -> c
+ | WSIGNALED s | WSTOPPED s -> 1 in
+ let result = {
+ res_job_name = job.job_name;
+ res_code = code;
+ res_tmpdir = dir;
+ res_output = dir // "output.txt"
+ } in
+ try cleanup result
+ with
+ | Failure msg ->
+ Syslog.error "job %s cleanup function failed: %s" job.job_name msg
+ | exn ->
+ Syslog.error "job %s cleanup function exception: %s"
+ job.job_name (Printexc.to_string exn)
+ );
+
(* This should be safe because the path cannot contain shell metachars. *)
let cmd = sprintf "rm -rf '%s'" dir in
ignore (Sys.command cmd)