]> arthur.barton.de Git - ngircd-alex.git/blob - src/ngircd/proc.c
New "module" proc.c/proc.h for generic process handling
[ngircd-alex.git] / src / ngircd / proc.c
1 /*
2  * ngIRCd -- The Next Generation IRC Daemon
3  * Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
4  *
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.
10  *
11  * Process management
12  */
13
14 #include "portab.h"
15
16 #include "imp.h"
17 #include <assert.h>
18 #include <errno.h>
19 #include <signal.h>
20 #include <string.h>
21 #include <unistd.h>
22
23 #include "log.h"
24 #include "io.h"
25
26 #include "exp.h"
27 #include "proc.h"
28
29 /**
30  * Initialize process structure.
31  */
32 GLOBAL void
33 Proc_InitStruct (PROC_STAT *proc)
34 {
35         assert(proc != NULL);
36         proc->pid = 0;
37         proc->pipe_fd = -1;
38 }
39
40 /**
41  * Fork a child process.
42  */
43 GLOBAL pid_t
44 Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short))
45 {
46         pid_t pid;
47
48         assert(proc != NULL);
49         assert(pipefds != NULL);
50         assert(cbfunc != NULL);
51
52         if (pipe(pipefds) != 0) {
53                 Log(LOG_ALERT, "Can't create output pipe for child process: %s!",
54                     strerror(errno));
55                 return -1;
56         }
57
58         pid = fork();
59         switch (pid) {
60         case -1:
61                 /* Error on fork: */
62                 Log(LOG_CRIT, "Can't fork child process: %s!", strerror(errno));
63                 close(pipefds[0]);
64                 close(pipefds[1]);
65                 return -1;
66         case 0:
67                 /* New child process: */
68                 close(pipefds[0]);
69                 return 0;
70         }
71
72         /* Old parent process: */
73         close(pipefds[1]);
74
75         if (!io_setnonblock(pipefds[0])
76          || !io_event_create(pipefds[0], IO_WANTREAD, cbfunc)) {
77                 Log(LOG_CRIT, "Can't register callback for child process: %s!",
78                     strerror(errno));
79                 close(pipefds[0]);
80                 return -1;
81         }
82
83         proc->pid = pid;
84         proc->pipe_fd = pipefds[0];
85         return pid;
86 }
87
88 /**
89  * Kill forked child process.
90  */
91 GLOBAL void
92 Proc_Kill(PROC_STAT *proc)
93 {
94         assert(proc != NULL);
95         assert(proc->pipe_fd >= 0);
96
97         io_close(proc->pipe_fd);
98         kill(proc->pid, SIGTERM);
99         Proc_InitStruct(proc);
100 }
101
102 /* -eof- */