aboutsummaryrefslogtreecommitdiff
path: root/src/util/os_priority.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/os_priority.c')
-rw-r--r--src/util/os_priority.c74
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 */
336pid_t 338pid_t
337GNUNET_OS_start_process_v (const char *filename, char *const argv[]) 339GNUNET_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)