diff options
Diffstat (limited to 'src/util/os_priority.c')
-rw-r--r-- | src/util/os_priority.c | 74 |
1 files changed, 72 insertions, 2 deletions
diff --git a/src/util/os_priority.c b/src/util/os_priority.c index b354ad995..7a6f0d65d 100644 --- a/src/util/os_priority.c +++ b/src/util/os_priority.c | |||
@@ -329,16 +329,43 @@ GNUNET_OS_start_process (struct GNUNET_DISK_PipeHandle *pipe_stdin, | |||
329 | /** | 329 | /** |
330 | * Start a process. | 330 | * Start a process. |
331 | * | 331 | * |
332 | * @param lsocks array of listen sockets to dup systemd-style (or NULL); | ||
333 | * must be NULL on platforms where dup is not supported | ||
332 | * @param filename name of the binary | 334 | * @param filename name of the binary |
333 | * @param argv NULL-terminated list of arguments to the process | 335 | * @param argv NULL-terminated list of arguments to the process |
334 | * @return process ID of the new process, -1 on error | 336 | * @return process ID of the new process, -1 on error |
335 | */ | 337 | */ |
336 | pid_t | 338 | pid_t |
337 | GNUNET_OS_start_process_v (const char *filename, char *const argv[]) | 339 | GNUNET_OS_start_process_v (const int *lsocks, |
340 | const char *filename, char *const argv[]) | ||
338 | { | 341 | { |
339 | #ifndef MINGW | 342 | #ifndef MINGW |
340 | pid_t ret; | 343 | pid_t ret; |
341 | 344 | char lpid[16]; | |
345 | char fds[16]; | ||
346 | int i; | ||
347 | int j; | ||
348 | int k; | ||
349 | int tgt; | ||
350 | int flags; | ||
351 | int *lscp; | ||
352 | unsigned int ls; | ||
353 | |||
354 | lscp = NULL; | ||
355 | ls = 0; | ||
356 | if (lsocks != NULL) | ||
357 | { | ||
358 | i = 0; | ||
359 | while (-1 != (k = lsocks[i++])) | ||
360 | { | ||
361 | flags = fcntl (k, F_GETFD); | ||
362 | GNUNET_assert (flags >= 0); | ||
363 | flags &= ~FD_CLOEXEC; | ||
364 | (void) fcntl (k, F_SETFD, flags); | ||
365 | GNUNET_array_append (lscp, ls, k); | ||
366 | } | ||
367 | GNUNET_array_append (lscp, ls, -1); | ||
368 | } | ||
342 | #if HAVE_WORKING_VFORK | 369 | #if HAVE_WORKING_VFORK |
343 | ret = vfork (); | 370 | ret = vfork (); |
344 | #else | 371 | #else |
@@ -366,6 +393,48 @@ GNUNET_OS_start_process_v (const char *filename, char *const argv[]) | |||
366 | } | 393 | } |
367 | return ret; | 394 | return ret; |
368 | } | 395 | } |
396 | if (lscp != NULL) | ||
397 | { | ||
398 | /* read systemd documentation... */ | ||
399 | GNUNET_snprintf (lpid, sizeof (lpid), "%u", getpid()); | ||
400 | setenv ("LISTEN_PID", lpid, 1); | ||
401 | i = 0; | ||
402 | tgt = 3; | ||
403 | while (-1 != lscp[i]) | ||
404 | { | ||
405 | j = i + 1; | ||
406 | while (-1 != lscp[j]) | ||
407 | { | ||
408 | if (lscp[j] == tgt) | ||
409 | { | ||
410 | /* dup away */ | ||
411 | k = dup (lscp[j]); | ||
412 | GNUNET_assert (-1 != k); | ||
413 | GNUNET_assert (0 == close (lscp[j])); | ||
414 | lscp[j] = k; | ||
415 | break; | ||
416 | } | ||
417 | j++; | ||
418 | } | ||
419 | if (lscp[i] != tgt) | ||
420 | { | ||
421 | /* Bury any existing FD, no matter what; they should all be closed | ||
422 | on exec anyway and the important onces have been dup'ed away */ | ||
423 | (void) close (tgt); | ||
424 | GNUNET_assert (-1 != dup2 (lscp[i], tgt)); | ||
425 | } | ||
426 | /* set close-on-exec flag */ | ||
427 | flags = fcntl (tgt, F_GETFD); | ||
428 | GNUNET_assert (flags >= 0); | ||
429 | flags &= ~FD_CLOEXEC; | ||
430 | (void) fcntl (tgt, F_SETFD, flags); | ||
431 | tgt++; | ||
432 | i++; | ||
433 | } | ||
434 | GNUNET_snprintf (fds, sizeof (fds), "%u", i); | ||
435 | setenv ("LISTEN_FDS", fds, 1); | ||
436 | } | ||
437 | GNUNET_array_grow (lscp, ls, 0); | ||
369 | execvp (filename, argv); | 438 | execvp (filename, argv); |
370 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "execvp", filename); | 439 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "execvp", filename); |
371 | _exit (1); | 440 | _exit (1); |
@@ -379,6 +448,7 @@ GNUNET_OS_start_process_v (const char *filename, char *const argv[]) | |||
379 | char *non_const_filename = NULL; | 448 | char *non_const_filename = NULL; |
380 | int filenamelen = 0; | 449 | int filenamelen = 0; |
381 | 450 | ||
451 | GNUNET_assert (lsocks == NULL); | ||
382 | /* Count the number of arguments */ | 452 | /* Count the number of arguments */ |
383 | arg = argv; | 453 | arg = argv; |
384 | while (*arg) | 454 | while (*arg) |