python:tests: Store keys as bytes rather than as lists of ints
[samba.git] / lib / util / tfork.h
1 /*
2    fork on steroids to avoid SIGCHLD and waitpid
3
4    Copyright (C) Stefan Metzmacher 2010
5    Copyright (C) Ralph Boehme 2017
6
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.
11
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.
16
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/>.
19 */
20
21 #ifndef LIB_UTIL_TFORK_H
22 #define LIB_UTIL_TFORK_H
23
24 struct tfork;
25
26 /**
27  * @brief a fork() that avoids SIGCHLD and waitpid
28  *
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
31  * wait()ing for it.
32  *
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()
36  * without blocking.
37  *
38  * The child process will start with SIGCHLD handler set to SIG_DFL.
39  *
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.
45  *
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.
50  **/
51 struct tfork *tfork_create(void);
52
53 /**
54  * @brief Return the child pid from tfork_create()
55  *
56  * @param[in]   t    Pointer to struct tfork returned by tfork_create()
57  *
58  * @return           In the caller this returns the pid of the child,
59  *                   in the child this returns 0.
60  **/
61 pid_t tfork_child_pid(const struct tfork *t);
62
63 /**
64  * @brief Return an event fd that signals child termination
65  *
66  * @param[in]   t    Pointer to struct tfork returned by tfork_create()
67  *
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
71  * abort().
72  *
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.
77  **/
78 int tfork_event_fd(struct tfork *t);
79
80 /**
81  * @brief Wait for the child to terminate and return its exit status
82  *
83  * @param[in]   t     Pointer-pointer to a struct tfork returned by
84  *                    tfork_create(). Upon successful completion t is freed and
85  *                    set to NULL.
86  *
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
91  *                    runstate.
92  *
93  * @return            The exit status of the child, -1 on error.
94  *
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.
97  **/
98 int tfork_status(struct tfork **_t, bool wait);
99
100 /**
101  * @brief Terminate the child discarding the exit status
102  *
103  * @param[in]   t     Pointer-pointer to a struct tfork returned by
104  *                    tfork_create(). Upon successful completion t is freed and
105  *                    set to NULL.
106  *
107  * @return            0 on success, -1 on error.
108  **/
109 int tfork_destroy(struct tfork **_t);
110
111 #endif /* LIB_UTIL_TFORK_H */