summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Protzenko <Jonathan.Protzenko@ens-lyon.org>2012-01-18 09:28:05 +0000
committerJonathan Protzenko <Jonathan.Protzenko@ens-lyon.org>2012-01-18 09:28:05 +0000
commitbb96c0b92c0683197716207c333032eb4ccafe3a (patch)
tree8c6db486bb56feaa8a0183eced9374fd679b2e51
parente710c98e323d94e379b8cb9ecf31419689ff1731 (diff)
downloadocaml-bb96c0b92c0683197716207c333032eb4ccafe3a.tar.gz
Fix #5421: do not leak fds in various open_proc* functions.
Patch by Till Varoquaux <till@janestreet.com> git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@12038 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
-rw-r--r--otherlibs/unix/unix.ml67
1 files changed, 47 insertions, 20 deletions
diff --git a/otherlibs/unix/unix.ml b/otherlibs/unix/unix.ml
index bfade03899..0adc41e213 100644
--- a/otherlibs/unix/unix.ml
+++ b/otherlibs/unix/unix.ml
@@ -839,27 +839,47 @@ let open_proc cmd proc input output toclose =
let open_process_in cmd =
let (in_read, in_write) = pipe() in
let inchan = in_channel_of_descr in_read in
- open_proc cmd (Process_in inchan) stdin in_write [in_read];
+ begin
+ try
+ open_proc cmd (Process_in inchan) stdin in_write [in_read];
+ with e ->
+ close_in inchan;
+ close in_write;
+ raise e
+ end;
close in_write;
inchan
let open_process_out cmd =
let (out_read, out_write) = pipe() in
let outchan = out_channel_of_descr out_write in
- open_proc cmd (Process_out outchan) out_read stdout [out_write];
+ begin
+ try
+ open_proc cmd (Process_out outchan) out_read stdout [out_write];
+ with e ->
+ close_out outchan;
+ close out_read;
+ raise e
+ end;
close out_read;
outchan
let open_process cmd =
let (in_read, in_write) = pipe() in
- let (out_read, out_write) = pipe() in
- let inchan = in_channel_of_descr in_read in
- let outchan = out_channel_of_descr out_write in
- open_proc cmd (Process(inchan, outchan)) out_read in_write
+ let fds_to_close = ref [in_read;in_write] in
+ try
+ let (out_read, out_write) = pipe() in
+ fds_to_close := [in_read;in_write;out_read;out_write];
+ let inchan = in_channel_of_descr in_read in
+ let outchan = out_channel_of_descr out_write in
+ open_proc cmd (Process(inchan, outchan)) out_read in_write
[in_read; out_write];
- close out_read;
- close in_write;
- (inchan, outchan)
+ close out_read;
+ close in_write;
+ (inchan, outchan)
+ with e ->
+ List.iter close !fds_to_close;
+ raise e
let open_proc_full cmd env proc input output error toclose =
let cloexec = List.for_all try_set_close_on_exec toclose in
@@ -875,17 +895,24 @@ let open_proc_full cmd env proc input output error toclose =
let open_process_full cmd env =
let (in_read, in_write) = pipe() in
- let (out_read, out_write) = pipe() in
- let (err_read, err_write) = pipe() in
- let inchan = in_channel_of_descr in_read in
- let outchan = out_channel_of_descr out_write in
- let errchan = in_channel_of_descr err_read in
- open_proc_full cmd env (Process_full(inchan, outchan, errchan))
- out_read in_write err_write [in_read; out_write; err_read];
- close out_read;
- close in_write;
- close err_write;
- (inchan, outchan, errchan)
+ let fds_to_close = ref [in_read;in_write] in
+ try
+ let (out_read, out_write) = pipe() in
+ fds_to_close := out_read::out_write:: !fds_to_close;
+ let (err_read, err_write) = pipe() in
+ fds_to_close := err_read::err_write:: !fds_to_close;
+ let inchan = in_channel_of_descr in_read in
+ let outchan = out_channel_of_descr out_write in
+ let errchan = in_channel_of_descr err_read in
+ open_proc_full cmd env (Process_full(inchan, outchan, errchan))
+ out_read in_write err_write [in_read; out_write; err_read];
+ close out_read;
+ close in_write;
+ close err_write;
+ (inchan, outchan, errchan)
+ with e ->
+ List.iter close !fds_to_close;
+ raise e
let find_proc_id fun_name proc =
try