X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Fproc.c;h=4da73474427861b75e5ac34d4d66cc364809ad44;hp=1e8cac36eea9d92a9eea14ba0b4797e5cbe3a063;hb=b130b35f48d19450240748425e12d21f2c38350f;hpb=9cd3494de92eccaa201f42fc8b02fc68c752aca8 diff --git a/src/ngircd/proc.c b/src/ngircd/proc.c index 1e8cac36..4da73474 100644 --- a/src/ngircd/proc.c +++ b/src/ngircd/proc.c @@ -1,30 +1,34 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2010 Alexander Barton (alex@barton.de) + * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. - * - * Process management */ #include "portab.h" -#include "imp.h" +/** + * @file + * Process management + */ + #include #include #include #include #include +#include #include +#include #include "log.h" #include "io.h" +#include "sighandlers.h" -#include "exp.h" #include "proc.h" /** @@ -42,9 +46,12 @@ Proc_InitStruct (PROC_STAT *proc) * Fork a child process. */ GLOBAL pid_t -Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short)) +Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short), int timeout) { pid_t pid; +#ifndef HAVE_ARC4RANDOM + unsigned int seed; +#endif assert(proc != NULL); assert(pipefds != NULL); @@ -56,6 +63,9 @@ Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short)) return -1; } +#ifndef HAVE_ARC4RANDOM + seed = (unsigned int)rand(); +#endif pid = fork(); switch (pid) { case -1: @@ -66,8 +76,17 @@ Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short)) return -1; case 0: /* New child process: */ +#ifdef HAVE_ARC4RANDOM_STIR + arc4random_stir(); +#endif +#ifndef HAVE_ARC4RANDOM + srand(seed ^ (unsigned int)time(NULL) ^ getpid()); +#endif + Signals_Exit(); signal(SIGTERM, Proc_GenericSignalHandler); + signal(SIGALRM, Proc_GenericSignalHandler); close(pipefds[0]); + alarm(timeout); return 0; } @@ -87,21 +106,6 @@ Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short)) return pid; } -/** - * Kill forked child process. - */ -GLOBAL void -Proc_Kill(PROC_STAT *proc) -{ - assert(proc != NULL); - - if (proc->pipe_fd > 0) - io_close(proc->pipe_fd); - if (proc->pid > 0) - kill(proc->pid, SIGTERM); - Proc_InitStruct(proc); -} - /** * Generic signal handler for forked child processes. */ @@ -112,6 +116,11 @@ Proc_GenericSignalHandler(int Signal) case SIGTERM: #ifdef DEBUG Log_Subprocess(LOG_DEBUG, "Child got TERM signal, exiting."); +#endif + exit(1); + case SIGALRM: +#ifdef DEBUG + Log_Subprocess(LOG_DEBUG, "Child got ALARM signal, exiting."); #endif exit(1); } @@ -119,7 +128,7 @@ Proc_GenericSignalHandler(int Signal) /** * Read bytes from a pipe of a forked child process. - * In addition, this function makes sure that the child process is dead + * In addition, this function makes sure that the child process is ignored * after all data has been read or a fatal error occurred. */ GLOBAL size_t @@ -136,14 +145,28 @@ Proc_Read(PROC_STAT *proc, void *buffer, size_t buflen) return 0; Log(LOG_CRIT, "Can't read from child process %ld: %s", proc->pid, strerror(errno)); + Proc_Close(proc); bytes_read = 0; + } else if (bytes_read == 0) { + /* EOF: clean up */ + LogDebug("Child process %ld: EOF reached, closing pipe.", + proc->pid); + Proc_Close(proc); } -#if DEBUG - else if (bytes_read == 0) - LogDebug("Can't read from child process %ld: EOF", proc->pid); -#endif - Proc_Kill(proc); return (size_t)bytes_read; } +/** + * Close pipe to a forked child process. + */ +GLOBAL void +Proc_Close(PROC_STAT *proc) +{ + /* Close socket, if it exists */ + if (proc->pipe_fd >= 0) + io_close(proc->pipe_fd); + + Proc_InitStruct(proc); +} + /* -eof- */