diff options
author | Keith Owens <k10@ocs.com.au> | 2011-09-16 17:55:28 +0200 |
---|---|---|
committer | Stef Walter <stefw@collabora.co.uk> | 2011-09-16 17:55:28 +0200 |
commit | 52747cc1752b8a8e35aee47db2f55d3a3c365ce3 (patch) | |
tree | b5085f6338d3bbb57c7f2f58388765b2dc28ccde /src/proxsmtpd.c | |
parent | 1994fa733c1c09202d85db952a28da26a19f0669 (diff) |
workaround for race between waitpid(-1) and waitpid(pid)
Sometimes waitpid(-1) in cb_check_data reaps a child that has just terminated,
before waitpid(pid) in wait_process can reap it. Linux waitpid(pid,,WNOHANG)
may not return an error if the child has already terminated, which results in
wait_process looping waiting for the child which has already terminated. The
symptom is a spurious "timeout waiting for filter command to exit".
Diffstat (limited to 'src/proxsmtpd.c')
-rw-r--r-- | src/proxsmtpd.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/src/proxsmtpd.c b/src/proxsmtpd.c index 278ecee..8f50d96 100644 --- a/src/proxsmtpd.c +++ b/src/proxsmtpd.c @@ -925,6 +925,11 @@ static int wait_process(spctx_t* sp, pid_t pid, int* status) switch(waitpid(pid, status, WNOHANG)) { case 0: + /* Linux may return 0 if the task has already terminated and was + * caught by waitpid(-1) above, double check it still exists. + */ + if (kill(pid, 0) < 0 && errno == ESRCH) + return 0; break; case -1: if(errno != ECHILD && errno != ESRCH) |