lib/util: only close the event_fd in tfork if the caller didn't call tfork_event_fd()
authorRalph Boehme <slow@samba.org>
Sat, 16 Sep 2017 08:22:31 +0000 (01:22 -0700)
committerRalph Boehme <slow@samba.org>
Sat, 16 Sep 2017 17:53:23 +0000 (19:53 +0200)
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>
lib/util/tfork.c
lib/util/tfork.h
selftest/knownfail.d/tfork [deleted file]

index 71f5e1b6ce91110316567a188c1042236e309975..ca4ab5076ceb604b96d9513abd74f0f273158df7 100644 (file)
@@ -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;
index 1fea2ba41295e03f16b19f9d54397575d7a29bf5..89c9f7295a81dcd6d8c2f1e9d8c5caa3da9c57fc 100644 (file)
@@ -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 (file)
index ea06b01..0000000
+++ /dev/null
@@ -1 +0,0 @@
-samba4.local.tfork.tfork_status_handle\(none\)