diff options
author | Jonathan Protzenko <Jonathan.Protzenko@ens-lyon.org> | 2012-01-18 09:28:05 +0000 |
---|---|---|
committer | Jonathan Protzenko <Jonathan.Protzenko@ens-lyon.org> | 2012-01-18 09:28:05 +0000 |
commit | bb96c0b92c0683197716207c333032eb4ccafe3a (patch) | |
tree | 8c6db486bb56feaa8a0183eced9374fd679b2e51 | |
parent | e710c98e323d94e379b8cb9ecf31419689ff1731 (diff) | |
download | ocaml-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.ml | 67 |
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 |