From: Ralph Boehme Date: Sat, 16 Sep 2017 08:22:31 +0000 (-0700) Subject: lib/util: only close the event_fd in tfork if the caller didn't call tfork_event_fd() X-Git-Tag: ldb-1.3.0~179 X-Git-Url: http://git.samba.org/?a=commitdiff_plain;h=6c36ea0737ae12fc97e4a024588e6a3845caf329;p=samba.git lib/util: only close the event_fd in tfork if the caller didn't call tfork_event_fd() Make closing of the event_fd the global responsibility of the parent process if it called tfork_event_fd(). Bug: https://bugzilla.samba.org/show_bug.cgi?id=13037 Signed-off-by: Ralph Boehme Reviewed-by: Gary Lockyer Reviewed-by: Stefan Metzmacher --- diff --git a/lib/util/tfork.c b/lib/util/tfork.c index 71f5e1b6ce9..ca4ab5076ce 100644 --- a/lib/util/tfork.c +++ b/lib/util/tfork.c @@ -795,9 +795,14 @@ pid_t tfork_child_pid(const struct tfork *t) return t->worker_pid; } -int tfork_event_fd(const struct tfork *t) +int tfork_event_fd(struct tfork *t) { - return t->event_fd; + int fd = t->event_fd; + + assert(t->event_fd != -1); + t->event_fd = -1; + + return fd; } int tfork_status(struct tfork **_t, bool wait) @@ -857,7 +862,10 @@ int tfork_status(struct tfork **_t, bool wait) } while ((pid == -1) && (errno == EINTR)); assert(pid == t->waiter_pid); - close(t->event_fd); + if (t->event_fd != -1) { + close(t->event_fd); + t->event_fd = -1; + } free(t); t = NULL; diff --git a/lib/util/tfork.h b/lib/util/tfork.h index 1fea2ba4129..89c9f7295a8 100644 --- a/lib/util/tfork.h +++ b/lib/util/tfork.h @@ -65,12 +65,17 @@ pid_t tfork_child_pid(const struct tfork *t); * * @param[in] t Pointer to struct tfork returned by tfork_create() * + * It is the callers responsibility to ensure that the event fd returned by + * tfork_event_fd() is closed. By calling tfork_event_fd() ownership of the fd + * is transferred to the caller, calling tfork_event_fd() again will trigger an + * abort(). + * * @return An fd that becomes readable when the child created with * tfork_create() terminates. It is guaranteed that a * subsequent call to tfork_status() will not block and return * the exit status of the child. **/ -int tfork_event_fd(const struct tfork *t); +int tfork_event_fd(struct tfork *t); /** * @brief Wait for the child to terminate and return its exit status diff --git a/selftest/knownfail.d/tfork b/selftest/knownfail.d/tfork deleted file mode 100644 index ea06b01a44e..00000000000 --- a/selftest/knownfail.d/tfork +++ /dev/null @@ -1 +0,0 @@ -samba4.local.tfork.tfork_status_handle\(none\)