summaryrefslogtreecommitdiff
path: root/lib/util
diff options
context:
space:
mode:
authorRalph Boehme <slow@samba.org>2017-09-16 01:22:31 -0700
committerRalph Boehme <slow@samba.org>2017-09-16 19:53:23 +0200
commit6c36ea0737ae12fc97e4a024588e6a3845caf329 (patch)
tree53d0a3b06edee154628ac4116fe75e3eb7ea377e /lib/util
parentf6a40ff2a1c133b6c30cf3ce29d7bb3ea005e3c8 (diff)
downloadsamba-6c36ea0737ae12fc97e4a024588e6a3845caf329.tar.gz
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 <slow@samba.org> Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> Reviewed-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'lib/util')
-rw-r--r--lib/util/tfork.c14
-rw-r--r--lib/util/tfork.h7
2 files changed, 17 insertions, 4 deletions
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