From 40ff8b345e8060d0b355312edcc5dbcca3029584 Mon Sep 17 00:00:00 2001 From: Zheng Li Date: Tue, 20 Apr 2010 19:05:48 +0100 Subject: [PATCH] Add some optional parameters to Stunnel.disconnect to cope with the stunnel zombie process issue and for future benefits. Signed-off-by: Zheng Li --- stunnel/stunnel.ml | 27 ++++++++++++++++++++++----- stunnel/stunnel.mli | 2 +- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/stunnel/stunnel.ml b/stunnel/stunnel.ml index 85c58a6..86e48d4 100644 --- a/stunnel/stunnel.ml +++ b/stunnel/stunnel.ml @@ -130,12 +130,29 @@ let config_file verify_cert extended_diagnosis host port = let ignore_exn f x = try f x with _ -> () -let disconnect x = +let rec disconnect ?(wait = true) ?(force = false) x = List.iter (ignore_exn Unix.close) [ x.fd ]; - match x.pid with - | FEFork pid -> ignore(Forkhelpers.waitpid pid) - | StdFork pid -> ignore(Unix.waitpid [] pid) - | Nopid -> () + let waiter, pid = match x.pid with + | FEFork pid -> + (fun () -> + (if wait then Forkhelpers.waitpid + else Forkhelpers.waitpid_nohang) pid), + Forkhelpers.getpid pid + | StdFork pid -> + (fun () -> + (if wait then Unix.waitpid [] + else Unix.waitpid [Unix.WNOHANG]) pid), + pid in + let res = + try waiter () + with Unix.Unix_error (Unix.ECHILD, _, _) -> pid, Unix.WEXITED 0 in + match res with + | 0, _ when force -> + (try Unix.kill pid Sys.sigkill + with Unix.Unix_error (Unix.ESRCH, _, _) ->()); + disconnect ~wait:wait ~force:force x + | _ -> () + (* With some probability, stunnel fails during its startup code before it reads the config data from us. Therefore we get a SIGPIPE writing the config data. diff --git a/stunnel/stunnel.mli b/stunnel/stunnel.mli index fa54919..570fb6b 100644 --- a/stunnel/stunnel.mli +++ b/stunnel/stunnel.mli @@ -53,7 +53,7 @@ val connect : string -> int -> t (** Disconnects from stunnel and cleans up *) -val disconnect : t -> unit +val disconnect : ?wait:bool -> ?force:bool -> t -> unit val diagnose_failure : t -> unit