Line data Source code
1 : #include <minipot_fork.h> 2 : #include <minipot_pipe_handler.h> 3 : #include <minipot_zmq_sender.h> 4 : #include <minipot_utils.h> 5 : #include <signal.h> 6 : #include <errno.h> 7 : #include <sys/wait.h> 8 : #include <sys/types.h> 9 : #include <sys/prctl.h> 10 : #include <unistd.h> 11 : #include <locale.h> 12 : #include "log.h" 13 : 14 0 : static void sigchld_handler(int sig) { 15 0 : int status; 16 0 : pid_t pid; 17 0 : int saved_errno = errno; 18 : // wait for any child process, if no child process exited return immediately 19 0 : while ((pid = waitpid(-1, &status, WNOHANG)) > 0) 20 : ; 21 0 : errno = saved_errno; 22 0 : } 23 : 24 0 : static void callback(uint8_t *payload, size_t payload_len, void *data) { 25 0 : if (minipot_zmq_sender_send((minipot_zmq_sender_t)data, payload, 26 : payload_len)) 27 0 : error("Couldn't send data to Sentinel Proxy"); 28 0 : } 29 : 30 : int minipot_fork(const struct minipot_config *config) { 31 0 : int pipe_end_fds[2]; 32 0 : assert(pipe(pipe_end_fds) != -1); 33 0 : pid_t pid = fork(); 34 0 : assert(pid != -1); 35 0 : if (pid == 0) { 36 : // child 37 : // When parent dies this process gets SIGKILL. 38 0 : prctl(PR_SET_PDEATHSIG, SIGKILL); 39 : // Unset any locale to hide system locales 40 0 : setlocale(LC_ALL, "C"); 41 : // read end 42 0 : close(pipe_end_fds[0]); 43 : // write end 44 0 : return pipe_end_fds[1]; 45 : } 46 : // parent 47 0 : signal(SIGCHLD, sigchld_handler); 48 : // write end 49 0 : close(pipe_end_fds[1]); 50 : // read end 51 0 : assert(minipot_set_nonblock(pipe_end_fds[0]) == 0); 52 0 : minipot_zmq_sender_t sender = 53 0 : minipot_zmq_sender_new(config->zmq_endopint, config->topic); 54 0 : assert(sender); 55 0 : minipot_pipe_handler_t mph = 56 0 : minipot_pipe_handler_new(pipe_end_fds[0], callback, sender); 57 0 : assert(mph); 58 0 : assert(minipot_pipe_handler_run(mph) == 0); 59 0 : minipot_pipe_handler_free(mph); 60 0 : minipot_zmq_sender_free(sender); 61 0 : close(pipe_end_fds[0]); 62 0 : exit(EXIT_SUCCESS); 63 : }