... | ... |
@@ -68,7 +68,7 @@ void receive_stdin_loop() |
68 | 68 |
|
69 | 69 |
char* cfg_file = 0; |
70 | 70 |
unsigned short port_no = 0; /* port on which we listen */ |
71 |
-int child_no = 0; /* number of children processing requests */ |
|
71 |
+int children_no = 0; /* number of children processing requests */ |
|
72 | 72 |
int debug = 0; |
73 | 73 |
int dont_fork = 0; |
74 | 74 |
int log_stderr = 0; |
... | ... |
@@ -80,8 +80,111 @@ char* names[MAX_LISTEN]; /* our names */ |
80 | 80 |
unsigned long addresses[MAX_LISTEN]; /* our ips */ |
81 | 81 |
int addresses_no=0; /* number of names/ips */ |
82 | 82 |
|
83 |
+/* ipc related globals */ |
|
84 |
+int process_no = 0; |
|
85 |
+#ifdef ROUTE_SRV |
|
86 |
+#endif |
|
83 | 87 |
|
84 | 88 |
|
89 |
+ |
|
90 |
+#define MAX_FD 32 /* maximum number of inherited open file descriptors, |
|
91 |
+ (normally it shouldn't be bigger than 3) */ |
|
92 |
+ |
|
93 |
+/* daemon init, return 0 on success, -1 on error */ |
|
94 |
+int daemonize(char* name) |
|
95 |
+{ |
|
96 |
+ pid_t pid; |
|
97 |
+ int r; |
|
98 |
+ |
|
99 |
+ if (log_stderr==0) |
|
100 |
+ openlog(name, LOG_PID, LOG_DAEMON); /* LOG_CONS, LOG_PERRROR ? */ |
|
101 |
+ |
|
102 |
+ if (chdir("/")<0){ |
|
103 |
+ LOG(L_CRIT,"cannot chroot:%s\n", strerror(errno)); |
|
104 |
+ goto error; |
|
105 |
+ } |
|
106 |
+ |
|
107 |
+ /* fork to become!= group leader*/ |
|
108 |
+ if ((pid=fork())<0){ |
|
109 |
+ LOG(L_CRIT, "Cannot fork:%s\n", strerror(errno)); |
|
110 |
+ goto error; |
|
111 |
+ } |
|
112 |
+ if (pid!=0){ |
|
113 |
+ /* parent process => exit*/ |
|
114 |
+ exit(0); |
|
115 |
+ } |
|
116 |
+ /* become session leader to drop the ctrl. terminal */ |
|
117 |
+ if (setsid()<0){ |
|
118 |
+ LOG(L_WARN, "setsid failed: %s\n",strerror(errno)); |
|
119 |
+ } |
|
120 |
+ /* fork again to drop group leadership */ |
|
121 |
+ if ((pid=fork())<0){ |
|
122 |
+ LOG(L_CRIT, "Cannot fork:%s\n", strerror(errno)); |
|
123 |
+ goto error; |
|
124 |
+ } |
|
125 |
+ if (pid!=0){ |
|
126 |
+ /*parent process => exit */ |
|
127 |
+ exit(0); |
|
128 |
+ } |
|
129 |
+ |
|
130 |
+ /* close any open file descriptors */ |
|
131 |
+ |
|
132 |
+ for (r=0;r<MAX_FD; r++){ |
|
133 |
+ if ((r==3) && log_stderr) continue; |
|
134 |
+ close(r); |
|
135 |
+ } |
|
136 |
+ |
|
137 |
+ return 0; |
|
138 |
+ |
|
139 |
+error: |
|
140 |
+ return -1; |
|
141 |
+} |
|
142 |
+ |
|
143 |
+ |
|
144 |
+ |
|
145 |
+/* main loop */ |
|
146 |
+int main_loop() |
|
147 |
+{ |
|
148 |
+ int r, i; |
|
149 |
+ pid_t pid; |
|
150 |
+ |
|
151 |
+ /* one "main" process and n children handling i/o */ |
|
152 |
+ |
|
153 |
+ if (dont_fork){ |
|
154 |
+ /* only one address */ |
|
155 |
+ if (udp_init(addresses[0],port_no)==-1) goto error; |
|
156 |
+ /* receive loop */ |
|
157 |
+ udp_rcv_loop(); |
|
158 |
+ }else{ |
|
159 |
+ for(r=0;r<addresses_no;r++){ |
|
160 |
+ for(i=0;i<children_no;i++){ |
|
161 |
+ if ((pid=fork())<0){ |
|
162 |
+ LOG(L_CRIT, "main_loop: Cannot fork\n"); |
|
163 |
+ goto error; |
|
164 |
+ } |
|
165 |
+ if (pid==0){ |
|
166 |
+ /* child */ |
|
167 |
+ if (udp_init(addresses[r], port_no)==-1) goto error; |
|
168 |
+ return udp_rcv_loop(); |
|
169 |
+ } |
|
170 |
+ } |
|
171 |
+ } |
|
172 |
+ } |
|
173 |
+ |
|
174 |
+ for(;;){ |
|
175 |
+ /* debug: instead of select */ |
|
176 |
+ sleep(1); |
|
177 |
+ } |
|
178 |
+ |
|
179 |
+ return 0; |
|
180 |
+ error: |
|
181 |
+ return -1; |
|
182 |
+ |
|
183 |
+} |
|
184 |
+ |
|
185 |
+ |
|
186 |
+ |
|
187 |
+ |
|
85 | 188 |
int main(int argc, char** argv) |
86 | 189 |
{ |
87 | 190 |
|
... | ... |
@@ -123,7 +226,7 @@ int main(int argc, char** argv) |
123 | 226 |
} |
124 | 227 |
break; |
125 | 228 |
case 'n': |
126 |
- child_no=strtol(optarg, tmp, 10); |
|
229 |
+ children_no=strtol(optarg, tmp, 10); |
|
127 | 230 |
if (tmp &&(*tmp)){ |
128 | 231 |
fprintf(stderr, "bad process number: -n %s\n", optarg); |
129 | 232 |
goto error; |
... | ... |
@@ -175,8 +278,8 @@ int main(int argc, char** argv) |
175 | 278 |
|
176 | 279 |
/* fill missing arguments with the default values*/ |
177 | 280 |
if (cfg_file==0) cfg_file=CFG_FILE; |
178 |
- if (port_no==0) port_no=SIP_PORT; |
|
179 |
- if (child_no==0) child_no=CHILD_NO; |
|
281 |
+ if (port_no<=0) port_no=SIP_PORT; |
|
282 |
+ if (children_no<=0) children_no=CHILD_NO; |
|
180 | 283 |
if (addresses_no==0) { |
181 | 284 |
/* get our address, only the first one */ |
182 | 285 |
if (uname (&myname) <0){ |
... | ... |
@@ -227,13 +330,12 @@ int main(int argc, char** argv) |
227 | 330 |
|
228 | 331 |
|
229 | 332 |
/* init_daemon? */ |
230 |
- |
|
231 |
- /* only one address for now */ |
|
232 |
- if (udp_init(addresses[0],port_no)==-1) goto error; |
|
233 |
- /* start/init other processes/threads ? */ |
|
234 |
- |
|
235 |
- /* receive loop */ |
|
236 |
- udp_rcv_loop(); |
|
333 |
+ if (!dont_fork){ |
|
334 |
+ if ( daemonize(argv[0]) <0 ) goto error; |
|
335 |
+ } |
|
336 |
+ |
|
337 |
+ |
|
338 |
+ return main_loop(); |
|
237 | 339 |
|
238 | 340 |
|
239 | 341 |
error: |