"Fossies" - the Fresh Open Source Software Archive 
Member "portfwd-0.29/src/entry.cc" (30 May 2005, 2266 Bytes) of package /linux/privat/old/portfwd-0.29.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 /*
2 entry.cc
3
4 $Id: entry.cc,v 1.2 2005/05/30 02:13:28 evertonm Exp $
5 */
6
7 #include <unistd.h>
8 #include <syslog.h>
9 #include <signal.h>
10 #include <sys/types.h>
11 #include <sys/wait.h>
12 #include <stdlib.h>
13
14 #include "iterator.hpp"
15 #include "entry.hpp"
16 #include "portfwd.h"
17 #include "forward.h"
18 #include "fd_set.h"
19
20 void grandchild_reaper(int sig)
21 {
22 int status;
23
24 pid_t gchild_pid = wait(&status);
25
26 if (gchild_pid == -1) {
27 syslog(LOG_ERR, "child: Error waiting pid of grandchild: %m");
28 return;
29 }
30
31 for (int fd = 0; fd < PORTFWD_MAX_FD; ++fd)
32 if (grandchild_pid[fd] == gchild_pid)
33 grandchild_pid[fd] = -1;
34
35 if (WIFEXITED(status)) {
36 ONVERBOSE(syslog(LOG_WARNING, "child: Grandchild with PID %d exited normally with exit status: %d\n", gchild_pid, WEXITSTATUS(status)));
37 return;
38 }
39
40 if (WIFSIGNALED(status))
41 syslog(LOG_NOTICE, "child: Grandchild received signal: %d\n", WTERMSIG(status));
42
43 syslog(LOG_ERR, "child: Grandchild with PID %d exited abnormally\n", gchild_pid);
44 }
45
46 void entry::show() const
47 {
48 syslog(LOG_INFO, "%s {\n", get_protoname(proto));
49 iterator<vector<proto_map*>,proto_map*> it(*proto_list);
50 it.start();
51 if (it.cont()) {
52 it.get()->show();
53 it.next();
54 }
55 for (; it.cont(); it.next()) {
56 syslog(LOG_INFO, "\n");
57 it.get()->show();
58 }
59 syslog(LOG_INFO, "}\n");
60 }
61
62 void entry::spawn(const proto_map *map) const
63 {
64 pid_t pid = fork();
65 if (pid) {
66 if (pid < 0)
67 syslog(LOG_ERR, "fork() failed: %m");
68
69 return;
70 }
71
72 /*
73 * Child
74 */
75
76 void (*prev_handler)(int);
77 prev_handler = signal(SIGPIPE, SIG_IGN);
78 if (prev_handler == SIG_ERR) {
79 syslog(LOG_ERR, "child: signal() failed for SIGPIPE blocking: %m");
80 return;
81 }
82
83 map->serve(proto);
84
85 syslog(LOG_ERR, "Child exiting (!)\n");
86 exit(1);
87 }
88
89 void entry::serve() const
90 {
91 if (!proto_list) {
92 syslog(LOG_WARNING, "No protocol entries\n");
93 return;
94 }
95
96 void (*prev_handler)(int);
97 prev_handler = signal(SIGCHLD, grandchild_reaper);
98 if (prev_handler == SIG_ERR) {
99 syslog(LOG_ERR, "signal() failed for grandchild handler: %m");
100 return;
101 }
102
103 iterator<vector<proto_map*>,proto_map*> it(*proto_list);
104 for (it.start(); it.cont(); it.next())
105 spawn(it.get());
106 }
107
108 /* Eof: entry.cc */