# sd_event_add_child

## NAME



           sd_event_add_child, sd_event_add_child_pidfd,
           sd_event_source_get_child_pid, sd_event_source_get_child_pidfd,
           sd_event_source_get_child_pidfd_own,
           sd_event_source_set_child_pidfd_own,
           sd_event_source_get_child_process_own,
           sd_event_source_set_child_process_own,
           sd_event_source_send_child_signal, sd_event_child_handler_t - Add
           a child process state change event source to an event loop
    


## SYNOPSIS



           **#include <systemd/sd-event.h>**
    
           **typedef struct sd_event_source sd_event_source;**
    
           **typedef int (*sd_event_child_handler_t)(sd_event_source ***_s_**,**
                                                   **const siginfo_t ***_si_**,**
                                                   **void ***_userdata_**);**
    
           **int sd_event_add_child(sd_event ***_event_**, sd_event_source ****_source_**,**
                                  **pid_t** _pid_**, int** _options_**,**
                                  **sd_event_child_handler_t** _handler_**,**
                                  **void ***_userdata_**);**
    
           **int sd_event_add_child_pidfd(sd_event ***_event_**,**
                                        **sd_event_source ****_source_**, int** _pidfd_**,**
                                        **int** _options_**,**
                                        **sd_event_child_handler_t** _handler_**,**
                                        **void ***_userdata_**);**
    
           **int sd_event_source_get_child_pid(sd_event_source ***_source_**,**
                                             **pid_t ***_ret_**);**
    
           **int sd_event_source_get_child_pidfd(sd_event_source ***_source_**);**
    
           **int sd_event_source_get_child_pidfd_own(sd_event_source ***_source_**);**
    
           **int sd_event_source_set_child_pidfd_own(sd_event_source ***_source_**,**
                                                   **int** _own_**);**
    
           **int**
                                                     **sd_event_source_get_child_process_own(sd_event_source ***_source_**);**
    
           **int sd_event_source_set_child_process_own(sd_event_source ***_source_**,**
                                                     **int** _own_**);**
    
           **int sd_event_source_send_child_signal(sd_event_source ***_source_**,**
                                                 **int** _sig_**,**
                                                 **const siginfo_t ***_info_**,**
                                                 **unsigned** _flags_**);**
    


## DESCRIPTION



           **sd_event_add_child()** adds a new child process state change event
           source to an event loop. The event loop object is specified in the
           _event_ parameter, the event source object is returned in the _source_
           parameter. The _pid_ parameter specifies the PID of the process to
           watch, which must be a direct child process of the invoking
           process. The _options_ parameter determines which state changes will
           be watched for. It must contain an OR-ed mask of **WEXITED**(watch
           for the child process terminating), **WSTOPPED**(watch for the child
           process being stopped by a signal), and **WCONTINUED**(watch for the
           child process being resumed by a signal). See waitid(2) for
           further information.
    
           The _handler_ must be a function to call when the process changes
           state or **NULL**. The handler function will be passed the _userdata_
           pointer, which may be chosen freely by the caller. The handler
           also receives a pointer to a siginfo_t structure containing
           information about the child process event. The handler may return
           negative to signal an error (see below), other return values are
           ignored. If _handler_ is **NULL** , a default handler that calls
           sd_event_exit(3) will be used.
    
           Only a single handler may be installed for a specific child
           process. The handler is enabled for a single event
           (**SD_EVENT_ONESHOT**), but this may be changed with
           sd_event_source_set_enabled(3). If the handler function returns a
           negative error code, it will either be disabled after the
           invocation, even if the **SD_EVENT_ON** mode was requested before, or
           it will cause the loop to terminate, see
           sd_event_source_set_exit_on_failure(3).
    
           To destroy an event source object use sd_event_source_unref(3),
           but note that the event source is only removed from the event loop
           when all references to the event source are dropped. To make sure
           an event source does not fire anymore, even when there's still a
           reference to it kept, consider setting the event source to
           **SD_EVENT_OFF** with sd_event_source_set_enabled(3).
    
           The **SIGCHLD** signal must be blocked in all threads before this
           function is called (using sigprocmask(2) or pthread_sigmask(3)).
    
           If the second parameter of **sd_event_add_child()** is passed as **NULL**
           no reference to the event source object is returned. In this case,
           the event source is considered "floating", and will be destroyed
           implicitly when the event loop itself is destroyed.
    
           Note that the _handler_ function is invoked at a time where the
           child process is not reaped yet (and thus still is exposed as a
           zombie process by the kernel). However, the child will be reaped
           automatically after the function returns. Child processes for
           which no child process state change event sources are installed
           will not be reaped by the event loop implementation.
    
           If the _handler_ parameter to **sd_event_add_child()** is **NULL** , and the
           event source fires, this will be considered a request to exit the
           event loop. In this case, the _userdata_ parameter, cast to an
           integer, is passed as the exit code parameter to sd_event_exit(3).
    
           If both a child process state change event source and a **SIGCHLD**
           signal event source is installed in the same event loop, the
           configured event source priorities decide which event source is
           dispatched first. If the signal handler is processed first, it
           should leave the child processes for which child process state
           change event sources are installed unreaped.
    
           **sd_event_add_child_pidfd()** is similar to **sd_event_add_child()** but
           takes a file descriptor referencing the process ("pidfd") instead
           of the numeric PID. A suitable file descriptor may be acquired via
           pidfd_open(2) and related calls. The passed file descriptor is not
           closed when the event source is freed again, unless
           **sd_event_source_set_child_pidfd_own()** is used to turn this
           behaviour on. Note that regardless which of **sd_event_add_child()**
           and **sd_event_add_child_pidfd()** is used for allocating an event
           source, the watched process has to be a direct child process of
           the invoking process. Also in both cases **SIGCHLD** has to be blocked
           in the invoking process.
    
           **sd_event_source_get_child_pid()** retrieves the configured PID of a
           child process state change event source created previously with
           **sd_event_add_child()**. It takes the event source object as the
           _source_ parameter and a pointer to a **pid_t** variable to return the
           process ID in.
    
           **sd_event_source_get_child_pidfd()** retrieves the file descriptor
           referencing the watched process ("pidfd"). The event loop
           internally makes use of pidfds to watch child processes,
           regardless of whether the individual event sources are allocated
           via **sd_event_add_child()** or **sd_event_add_child_pidfd()**. If the
           latter call was used to allocate the event source, this function
           returns the original file descriptor used for allocation. This
           call takes the event source object as the _source_ parameter and
           returns the numeric file descriptor.
    
           **sd_event_source_get_child_pidfd_own()** may be used to query whether
           the pidfd the event source encapsulates shall be closed when the
           event source is freed. This function returns zero if the pidfd
           shall be left open, and positive if it shall be closed
           automatically. By default, this setting defaults to on if the
           event source was allocated via **sd_event_add_child()** and off if it
           was allocated via **sd_event_add_child_pidfd()**. The
           **sd_event_source_set_child_pidfd_own()** function may be used to
           change the setting and takes a boolean parameter with the new
           setting.
    
           **sd_event_source_get_child_process_own()** may be used to query
           whether the process the event source watches shall be killed (with
           **SIGKILL**) and reaped when the event source is freed. This function
           returns zero if the process shell be left running, and positive if
           it shall be killed and reaped automatically. By default, this
           setting defaults to off. The
           **sd_event_source_set_child_process_own()** function may be used to
           change the setting and takes a boolean parameter with the new
           setting. Note that currently if the calling process is terminated
           abnormally the watched process might survive even thought the
           event source ceases to exist. This behaviour might change
           eventually.
    
           **sd_event_source_send_child_signal()** may be used to send a UNIX
           signal to the watched process via pidfd_send_signal(2). The
           specified parameters match those of the underlying system call,
           except that the _info_ is never modified (and is thus declared
           constant). Like for the underlying system call, the _flags_
           parameter currently must be zero.
    


## RETURN VALUE



           On success, these functions return 0 or a positive integer. On
           failure, they return a negative errno-style error code.
    
       **Errors**
           Returned errors may indicate the following problems:
    
           **-ENOMEM**
               Not enough memory to allocate an object.
    
           **-EINVAL**
               An invalid argument has been passed. This includes specifying
               an empty mask in _options_ or a mask which contains values
               different than a combination of **WEXITED** , **WSTOPPED** , and
               **WCONTINUED**.
    
           **-EBUSY**
               A handler is already installed for this child process, or
               **SIGCHLD** is not blocked.
    
           **-ESTALE**
               The event loop is already terminated.
    
           **-ECHILD**
               The event loop has been created in a different process,
               library or module instance.
    
           **-EDOM**
               The passed event source is not a child process event source.
    


## NOTES



           Functions described here are available as a shared library, which
           can be compiled against and linked to with the
           **libsystemd pkg-config**(1) file.
    
           The code described here uses getenv(3), which is declared to be
           not multi-thread-safe. This means that the code calling the
           functions described here must not call setenv(3) from a parallel
           thread. It is recommended to only do calls to **setenv()** from an
           early phase of the program when no other threads have been
           started.
    


## EXAMPLE



           **Example 1. Exit loop when the child terminates**
    
               /* SPDX-License-Identifier: MIT-0 */
    
               #define _GNU_SOURCE 1
               #include <assert.h>
               #include <stdio.h>
               #include <unistd.h>
               #include <systemd/sd-event.h>
    
               int main(int argc, char **argv) {
                 pid_t pid = fork();
                 assert(pid >= 0);
    
                 /* SIGCHLD signal must be blocked for sd_event_add_child to work */
                 sigset_t ss;
                 sigemptyset(&ss);
                 sigaddset(&ss, SIGCHLD);
                 sigprocmask(SIG_BLOCK, &ss, NULL);
    
                 if (pid == 0)  /* child */
                   sleep(1);
    
                 else {         /* parent */
                   sd_event *e = NULL;
                   int r;
    
                   /* Create the default event loop */
                   sd_event_default(&e);
                   assert(e);
    
                   /* We create a floating child event source (attached to 'e').
                    * The default handler will be called with 666 as userdata, which
                    * will become the exit value of the loop. */
                   r = sd_event_add_child(e, NULL, pid, WEXITED, NULL, (void*) 666);
                   assert(r >= 0);
    
                   r = sd_event_loop(e);
                   assert(r == 666);
    
                   sd_event_unref(e);
                 }
    
                 return 0;
               }
    


* * *