2 fork on steroids to avoid SIGCHLD and waitpid
4 Copyright (C) Stefan Metzmacher 2010
5 Copyright (C) Ralph Boehme 2017
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #ifndef LIB_UTIL_TFORK_H
22 #define LIB_UTIL_TFORK_H
27 * @brief a fork() that avoids SIGCHLD and waitpid
29 * This function is a solution to the problem of fork() requiring special
30 * preperations in the caller to handle SIGCHLD signals and to reap the child by
33 * The advantage over fork() is that the child process termination is signalled
34 * to the caller by making a pipe fd readable returned by tfork_event_fd(), in
35 * which case the exit status of the child can be fetched with tfork_status()
38 * The child process will start with SIGCHLD handler set to SIG_DFL.
40 * @return On success, a struct tfork. NULL on failure.
41 * Use tfork_worker_pid() to get the pid of the created
42 * child and tfork_event_fd() to get the file descriptor
43 * that can be used to poll for process termination and
44 * reading the child process exit status.
46 * @note There's one thing this thing can't protect us against and that is if a
47 * process installs a SIGCHLD handler from one thread while another thread is
48 * running inside tfork_create() or tfork_status() and the signal handler
49 * doesn't forward signals for exitted childs it didn't fork, ie our childs.
51 struct tfork
*tfork_create(void);
54 * @brief Return the child pid from tfork_create()
56 * @param[in] t Pointer to struct tfork returned by tfork_create()
58 * @return In the caller this returns the pid of the child,
59 * in the child this returns 0.
61 pid_t
tfork_child_pid(const struct tfork
*t
);
64 * @brief Return an event fd that signals child termination
66 * @param[in] t Pointer to struct tfork returned by tfork_create()
68 * It is the callers responsibility to ensure that the event fd returned by
69 * tfork_event_fd() is closed. By calling tfork_event_fd() ownership of the fd
70 * is transferred to the caller, calling tfork_event_fd() again will trigger an
73 * @return An fd that becomes readable when the child created with
74 * tfork_create() terminates. It is guaranteed that a
75 * subsequent call to tfork_status() will not block and return
76 * the exit status of the child.
78 int tfork_event_fd(struct tfork
*t
);
81 * @brief Wait for the child to terminate and return its exit status
83 * @param[in] t Pointer-pointer to a struct tfork returned by
84 * tfork_create(). Upon successful completion t is freed and
87 * @param[in] wait Whether to wait for the child to change state. If wait is
88 * false, and the child hasn't changed state, tfork_status()
89 * will return -1 with errno set to EAGAIN. If wait is true,
90 * tfork_status() will block waiting for the child to change
93 * @return The exit status of the child, -1 on error.
95 * @note We overload the return value a bit, but a process exit status is pretty
96 * much guaranteed to be a 16-bit int and can't be -1.
98 int tfork_status(struct tfork
**_t
, bool wait
);
101 * @brief Terminate the child discarding the exit status
103 * @param[in] t Pointer-pointer to a struct tfork returned by
104 * tfork_create(). Upon successful completion t is freed and
107 * @return 0 on success, -1 on error.
109 int tfork_destroy(struct tfork
**_t
);
111 #endif /* LIB_UTIL_TFORK_H */