2 * ngIRCd -- The Next Generation IRC Daemon
3 * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * Please read the file COPYING, README and AUTHORS for more information.
24 #include <sys/types.h>
30 #include "sighandlers.h"
35 * Initialize process structure.
38 Proc_InitStruct (PROC_STAT *proc)
46 * Fork a child process.
49 Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short), int timeout)
52 #ifndef HAVE_ARC4RANDOM
57 assert(pipefds != NULL);
58 assert(cbfunc != NULL);
60 if (pipe(pipefds) != 0) {
61 Log(LOG_ALERT, "Can't create output pipe for child process: %s!",
66 #ifndef HAVE_ARC4RANDOM
67 seed = (unsigned int)rand();
73 Log(LOG_CRIT, "Can't fork child process: %s!", strerror(errno));
78 /* New child process: */
79 #ifdef HAVE_ARC4RANDOM_STIR
82 #ifndef HAVE_ARC4RANDOM
83 srand(seed ^ (unsigned int)time(NULL) ^ getpid());
86 signal(SIGTERM, Proc_GenericSignalHandler);
87 signal(SIGALRM, Proc_GenericSignalHandler);
93 /* Old parent process: */
96 if (!io_setnonblock(pipefds[0])
97 || !io_event_create(pipefds[0], IO_WANTREAD, cbfunc)) {
98 Log(LOG_CRIT, "Can't register callback for child process: %s!",
105 proc->pipe_fd = pipefds[0];
110 * Generic signal handler for forked child processes.
113 Proc_GenericSignalHandler(int Signal)
118 Log_Subprocess(LOG_DEBUG, "Child got TERM signal, exiting.");
123 Log_Subprocess(LOG_DEBUG, "Child got ALARM signal, exiting.");
130 * Read bytes from a pipe of a forked child process.
131 * In addition, this function makes sure that the child process is ignored
132 * after all data has been read or a fatal error occurred.
135 Proc_Read(PROC_STAT *proc, void *buffer, size_t buflen)
137 ssize_t bytes_read = 0;
139 assert(buffer != NULL);
142 bytes_read = read(proc->pipe_fd, buffer, buflen);
143 if (bytes_read < 0) {
146 Log(LOG_CRIT, "Can't read from child process %ld: %s",
147 proc->pid, strerror(errno));
150 } else if (bytes_read == 0) {
152 LogDebug("Child process %ld: EOF reached, closing pipe.",
156 return (size_t)bytes_read;
160 * Close pipe to a forked child process.
163 Proc_Close(PROC_STAT *proc)
165 /* Close socket, if it exists */
166 if (proc->pipe_fd >= 0)
167 io_close(proc->pipe_fd);
169 Proc_InitStruct(proc);