ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/util.C
(Generate patch)

Comparing gvpe/src/util.C (file contents):
Revision 1.22 by pcg, Thu Aug 7 17:54:27 2008 UTC vs.
Revision 1.27 by root, Wed Jul 17 16:40:57 2013 UTC

1/* 1/*
2 util.C -- process management and other utility functions 2 util.C -- process management and other utility functions
3 Copyright (C) 2003-2008 Marc Lehmann <gvpe@schmorp.de> 3 Copyright (C) 2003-2011 Marc Lehmann <gvpe@schmorp.de>
4 4
5 Some of these are taken from tinc, see the AUTHORS file. 5 Some of these are taken from tinc, see the AUTHORS file.
6 6
7 This file is part of GVPE. 7 This file is part of GVPE.
8 8
35 35
36#include <cstdio> 36#include <cstdio>
37#include <cstdlib> 37#include <cstdlib>
38#include <cstring> 38#include <cstring>
39 39
40#include <queue>
41
40#include <errno.h> 42#include <errno.h>
41#include <signal.h> 43#include <signal.h>
42#include <sys/types.h> 44#include <sys/types.h>
43#include <sys/wait.h> 45#include <sys/wait.h>
44#include <unistd.h> 46#include <unistd.h>
45#include <time.h> 47#include <time.h>
46 48
49#if ENABLE_PTHREADS
50# include <pthread.h>
51#endif
52
53#include <openssl/rand.h>
54
47#include "netcompat.h" 55#include "netcompat.h"
48 56
49#include "gettext.h" 57#include "gettext.h"
50#include "pidfile.h" 58#include "pidfile.h"
51#include "dropin.h" 59#include "dropin.h"
132 log_to (LOGTO_SYSLOG); 140 log_to (LOGTO_SYSLOG);
133 } 141 }
134 else 142 else
135 log_to (LOGTO_SYSLOG | LOGTO_STDERR); 143 log_to (LOGTO_SYSLOG | LOGTO_STDERR);
136 144
137 slog (L_INFO, _("gvpe daemon %s (%s %s) starting"), VERSION, __DATE__, __TIME__); 145 slog (L_INFO, _("gvpe daemon %s (%s %s) starting up."), VERSION, __DATE__, __TIME__);
138 146
139 return 0; 147 return 0;
140} 148}
141 149
150/*****************************************************************************/
151
152pid_t
142bool run_script (const run_script_cb &cb, bool wait) 153run_script (const run_script_cb &cb, bool wait)
143{ 154{
155 sigset_t oldset;
156
144 if (wait) 157 if (wait)
145 signal (SIGCHLD, SIG_DFL); // this is extremely ugly, but I did not feel like implementing a complete wait() event logic. It's easier to write this long comment to make your editor happy. 158 {
159 sigset_t sigchld;
160 sigemptyset (&sigchld);
161 sigaddset (&sigchld, SIGCHLD);
162 sigprocmask (SIG_BLOCK, &sigchld, &oldset);
163 }
146 164
147 int pid = fork (); 165 pid_t pid = fork ();
148 166
149 if (pid == 0) 167 if (pid == 0)
150 { 168 {
169 sigprocmask (SIG_SETMASK, &oldset, 0);
170
151 execl ("/bin/sh", "/bin/sh", "-c", cb (), (char *) 0); 171 execl ("/bin/sh", "/bin/sh", "-c", cb (), (char *) 0);
152 exit (EXIT_FAILURE); 172 exit (EXIT_FAILURE);
153 } 173 }
154 else if (pid > 0) 174 else if (pid > 0)
155 { 175 {
156 if (wait) 176 if (wait)
157 { 177 {
158 int status; 178 int status;
159 int res = waitpid (pid, &status, 0); 179 int res = waitpid (pid, &status, 0);
160 180
161 signal (SIGCHLD, SIG_IGN); 181 sigprocmask (SIG_SETMASK, &oldset, 0);
162 182
163 if (res < 0) 183 if (res < 0)
164 { 184 {
165 slog (L_WARN, _("waiting for an external command failed: %s."), 185 slog (L_WARN, _("waiting for an external command failed: %s."),
166 strerror (errno)); 186 strerror (errno));
167 return false; 187 return 0;
168 } 188 }
169 else if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_SUCCESS) 189 else if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_SUCCESS)
170 { 190 {
171 slog (L_WARN, _("external command returned with exit status %d (%04x)."), 191 slog (L_WARN, _("external command returned with exit status %d (%04x)."),
172 WEXITSTATUS (status), status); 192 WEXITSTATUS (status), status);
173 return false; 193 return 0;
174 } 194 }
175 } 195 }
176 } 196 }
177 else 197 else
178 { 198 {
179 slog (L_ERR, _("unable to fork, exiting: %s"), strerror (errno)); 199 slog (L_ERR, _("unable to fork, exiting: %s"), strerror (errno));
180 exit (EXIT_FAILURE); 200 exit (EXIT_FAILURE);
181 } 201 }
182 202
203 return pid;
204}
205
206/*****************************************************************************/
207
208#if 0 /* not yet used */
209
210#if ENABLE_PTHREADS
211struct async_cb
212{
213 callback<void ()> work_cb;
214 callback<void ()> done_cb;
215};
216
217static ev::async async_done_w;
218static std::queue< callback<void ()> > async_q;
219
220static callback<void ()> work_cb;
221
222static void *
223async_exec (void *)
224{
225 work_cb ();
226 async_done_w.send ();
227
183 return true; 228 return 0;
184} 229}
230
231static void
232async_q_next ()
233{
234 work_cb = async_q.front (); async_q.pop ();
235
236 sigset_t fullsigset, oldsigset;
237 pthread_attr_t attr;
238 pthread_t tid;
239
240 pthread_attr_init (&attr);
241 pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
242 //pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN < X_STACKSIZE ? X_STACKSIZE : PTHREAD_STACK_MIN);
243 sigfillset (&fullsigset);
244 pthread_sigmask (SIG_SETMASK, &fullsigset, &oldsigset);
245
246 if (pthread_create (&tid, &attr, async_exec, 0))
247 async_exec (0);
248
249 pthread_sigmask (SIG_SETMASK, &oldsigset, 0);
250 pthread_attr_destroy (&attr);
251}
252
253namespace {
254 void
255 async_done (ev::async &w, int revents)
256 {
257 callback<void ()> done_cb = async_q.front (); async_q.pop ();
258
259 if (async_q.empty ())
260 async_done_w.stop ();
261 else
262 async_q_next ();
263
264 done_cb ();
265 }
266};
267
268void
269async (callback<void ()> work_cb, callback<void ()> done_cb)
270{
271 bool was_empty = async_q.empty ();
272
273 async_q.push (work_cb);
274 async_q.push (done_cb);
275
276 if (was_empty)
277 {
278 async_done_w.set<async_done> ();
279 async_done_w.start ();
280 async_q_next ();
281 }
282}
283
284#else
285
286void
287async (callback<void ()> work_cb, callback<void ()> done_cb)
288{
289 work_cb ();
290 done_cb ();
291}
292
293#endif
294
295#endif
296
297/*****************************************************************************/
298
299void hexdump (const char *header, void *data, int len)
300{
301 u8 *p = (u8 *)data;
302
303 printf ("%s:", header);
304
305 while (len--)
306 printf (" %02x", *p++);
307
308 printf ("\n");
309}
310
311/*****************************************************************************/
185 312
186#if ENABLE_HTTP_PROXY 313#if ENABLE_HTTP_PROXY
187// works like strdup 314// works like strdup
188u8 * 315u8 *
189base64_encode (const u8 *data, unsigned int len) 316base64_encode (const u8 *data, unsigned int len)
254 p[4] = 0xff; 381 p[4] = 0xff;
255 p[5] = 0xff; 382 p[5] = 0xff;
256 } 383 }
257} 384}
258 385
386/*****************************************************************************/
387
388void rand_fill (void *data, int len)
389{
390 int l = RAND_bytes ((unsigned char *)data, len);
391
392 if (l > 0)
393 return;
394 else if (l == 0)
395 slog (L_WARN, _("Not enough random entropy to generate secure keys. Using weaker pseudo-random session keys."));
396 else
397 fatal (_("RAND_bytes failed, aborting."));
398}
399

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines