aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--src/arm/arm_api.c3
-rw-r--r--src/arm/do_start_process.c6
-rw-r--r--src/arm/gnunet-service-arm.c34
-rw-r--r--src/arm/gnunet-service-arm.h13
-rw-r--r--src/arm/gnunet-service-arm_interceptor.c86
-rw-r--r--src/include/gnunet_network_lib.h1
-rw-r--r--src/include/gnunet_os_lib.h5
-rw-r--r--src/util/os_priority.c74
9 files changed, 196 insertions, 31 deletions
diff --git a/ChangeLog b/ChangeLog
index 861d8bd25..2761b94d9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
1Wed Jun 23 16:34:38 CEST 2010
2 Added support for systemd-compatible passing of listen-sockets
3 by ARM to services as well as systemd compatibility for gnunet-service-arm
4 itself. At least for non-MINGW systems this should work.
5
1Sat Jun 5 18:08:39 CEST 2010 6Sat Jun 5 18:08:39 CEST 2010
2 Added support for UNIX domain sockets, code also defaults to 7 Added support for UNIX domain sockets, code also defaults to
3 them when available. 8 them when available.
diff --git a/src/arm/arm_api.c b/src/arm/arm_api.c
index 083031e78..6c2b53a71 100644
--- a/src/arm/arm_api.c
+++ b/src/arm/arm_api.c
@@ -434,7 +434,8 @@ arm_service_report (void *cls,
434 GNUNET_free (lopostfix); 434 GNUNET_free (lopostfix);
435 return; 435 return;
436 } 436 }
437 pid = do_start_process (loprefix, 437 pid = do_start_process (NULL,
438 loprefix,
438 binary, 439 binary,
439 "-c", config, 440 "-c", config,
440#if DEBUG_ARM 441#if DEBUG_ARM
diff --git a/src/arm/do_start_process.c b/src/arm/do_start_process.c
index 357d39920..d616ac2b7 100644
--- a/src/arm/do_start_process.c
+++ b/src/arm/do_start_process.c
@@ -7,12 +7,14 @@
7 * limitation that it does NOT allow passing command line arguments 7 * limitation that it does NOT allow passing command line arguments
8 * with spaces to the new process. 8 * with spaces to the new process.
9 * 9 *
10 * @param lsocks array of listen sockets to dup starting at fd3 (systemd-style), or NULL
10 * @param first_arg first argument for argv (may be an empty string) 11 * @param first_arg first argument for argv (may be an empty string)
11 * @param ... more arguments, NULL terminated 12 * @param ... more arguments, NULL terminated
12 * @return PID of the started process, -1 on error 13 * @return PID of the started process, -1 on error
13 */ 14 */
14static pid_t 15static pid_t
15do_start_process (const char *first_arg, ...) 16do_start_process (const int *lsocks,
17 const char *first_arg, ...)
16{ 18{
17 va_list ap; 19 va_list ap;
18 char **argv; 20 char **argv;
@@ -86,7 +88,7 @@ do_start_process (const char *first_arg, ...)
86 while (NULL != (arg = (va_arg (ap, const char*)))); 88 while (NULL != (arg = (va_arg (ap, const char*))));
87 va_end (ap); 89 va_end (ap);
88 argv[argv_size] = NULL; 90 argv[argv_size] = NULL;
89 pid = GNUNET_OS_start_process_v (argv[0], argv); 91 pid = GNUNET_OS_start_process_v (lsocks, argv[0], argv);
90 while (argv_size > 0) 92 while (argv_size > 0)
91 GNUNET_free (argv[--argv_size]); 93 GNUNET_free (argv[--argv_size]);
92 GNUNET_free (argv); 94 GNUNET_free (argv);
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c
index ab96906a7..59f48a58c 100644
--- a/src/arm/gnunet-service-arm.c
+++ b/src/arm/gnunet-service-arm.c
@@ -344,7 +344,8 @@ free_entry (struct ServiceList *pos)
344 * @param sl identifies service to start 344 * @param sl identifies service to start
345 */ 345 */
346static void 346static void
347start_process (struct ServiceList *sl) 347start_process (struct ServiceList *sl,
348 const int *lsocks)
348{ 349{
349 char *loprefix; 350 char *loprefix;
350 char *options; 351 char *options;
@@ -415,14 +416,16 @@ start_process (struct ServiceList *sl)
415 sl->name, sl->binary, sl->config); 416 sl->name, sl->binary, sl->config);
416#endif 417#endif
417 if (GNUNET_YES == use_debug) 418 if (GNUNET_YES == use_debug)
418 sl->pid = do_start_process (loprefix, 419 sl->pid = do_start_process (lsocks,
420 loprefix,
419 sl->binary, 421 sl->binary,
420 "-c", sl->config, 422 "-c", sl->config,
421 "-L", "DEBUG", 423 "-L", "DEBUG",
422 options, 424 options,
423 NULL); 425 NULL);
424 else 426 else
425 sl->pid = do_start_process (loprefix, 427 sl->pid = do_start_process (lsocks,
428 loprefix,
426 sl->binary, 429 sl->binary,
427 "-c", sl->config, 430 "-c", sl->config,
428 options, 431 options,
@@ -442,9 +445,13 @@ start_process (struct ServiceList *sl)
442 * 445 *
443 * @param client who is asking for this 446 * @param client who is asking for this
444 * @param servicename name of the service to start 447 * @param servicename name of the service to start
448 * @param lsocks -1 terminated list of listen sockets to pass (systemd style), or NULL
449 * @return GNUNET_OK on success, GNUNET_SYSERR on error
445 */ 450 */
446void 451int
447start_service (struct GNUNET_SERVER_Client *client, const char *servicename) 452start_service (struct GNUNET_SERVER_Client *client,
453 const char *servicename,
454 const int *lsocks)
448{ 455{
449 struct ServiceList *sl; 456 struct ServiceList *sl;
450 char *binary; 457 char *binary;
@@ -457,7 +464,7 @@ start_service (struct GNUNET_SERVER_Client *client, const char *servicename)
457 _("ARM is shutting down, service `%s' not started.\n"), 464 _("ARM is shutting down, service `%s' not started.\n"),
458 servicename); 465 servicename);
459 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); 466 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN);
460 return; 467 return GNUNET_SYSERR;
461 } 468 }
462 sl = find_name (servicename); 469 sl = find_name (servicename);
463 if (sl != NULL) 470 if (sl != NULL)
@@ -467,7 +474,7 @@ start_service (struct GNUNET_SERVER_Client *client, const char *servicename)
467 sl->next = running; 474 sl->next = running;
468 running = sl; 475 running = sl;
469 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_UP); 476 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_UP);
470 return; 477 return GNUNET_SYSERR;
471 } 478 }
472 if (GNUNET_OK != 479 if (GNUNET_OK !=
473 GNUNET_CONFIGURATION_get_value_string (cfg, 480 GNUNET_CONFIGURATION_get_value_string (cfg,
@@ -477,7 +484,7 @@ start_service (struct GNUNET_SERVER_Client *client, const char *servicename)
477 _("Binary implementing service `%s' not known!\n"), 484 _("Binary implementing service `%s' not known!\n"),
478 servicename); 485 servicename);
479 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); 486 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN);
480 return; 487 return GNUNET_SYSERR;
481 } 488 }
482 if ((GNUNET_OK != 489 if ((GNUNET_OK !=
483 GNUNET_CONFIGURATION_get_value_filename (cfg, 490 GNUNET_CONFIGURATION_get_value_filename (cfg,
@@ -492,7 +499,7 @@ start_service (struct GNUNET_SERVER_Client *client, const char *servicename)
492 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); 499 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN);
493 GNUNET_free (binary); 500 GNUNET_free (binary);
494 GNUNET_free_non_null (config); 501 GNUNET_free_non_null (config);
495 return; 502 return GNUNET_SYSERR;
496 } 503 }
497 (void) stop_listening (servicename); 504 (void) stop_listening (servicename);
498 sl = GNUNET_malloc (sizeof (struct ServiceList)); 505 sl = GNUNET_malloc (sizeof (struct ServiceList));
@@ -505,9 +512,10 @@ start_service (struct GNUNET_SERVER_Client *client, const char *servicename)
505 sl->restartAt = GNUNET_TIME_UNIT_FOREVER_ABS; 512 sl->restartAt = GNUNET_TIME_UNIT_FOREVER_ABS;
506 513
507 running = sl; 514 running = sl;
508 start_process (sl); 515 start_process (sl, lsocks);
509 if (NULL != client) 516 if (NULL != client)
510 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_UP); 517 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_UP);
518 return GNUNET_OK;
511} 519}
512 520
513 521
@@ -610,7 +618,7 @@ handle_start (void *cls,
610 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 618 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
611 return; 619 return;
612 } 620 }
613 start_service (client, servicename); 621 start_service (client, servicename, NULL);
614 GNUNET_SERVER_receive_done (client, GNUNET_OK); 622 GNUNET_SERVER_receive_done (client, GNUNET_OK);
615} 623}
616 624
@@ -776,7 +784,7 @@ delayed_restart_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
776 { 784 {
777 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 785 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
778 _("Restarting service `%s'.\n"), pos->name); 786 _("Restarting service `%s'.\n"), pos->name);
779 start_process (pos); 787 start_process (pos, NULL);
780 } 788 }
781 else 789 else
782 { 790 {
@@ -1071,7 +1079,7 @@ run (void *cls,
1071 pos = strtok (defaultservices, " "); 1079 pos = strtok (defaultservices, " ");
1072 while (pos != NULL) 1080 while (pos != NULL)
1073 { 1081 {
1074 start_service (NULL, pos); 1082 start_service (NULL, pos, NULL);
1075 pos = strtok (NULL, " "); 1083 pos = strtok (NULL, " ");
1076 } 1084 }
1077 } 1085 }
diff --git a/src/arm/gnunet-service-arm.h b/src/arm/gnunet-service-arm.h
index 77dfb8c6c..632b46b09 100644
--- a/src/arm/gnunet-service-arm.h
+++ b/src/arm/gnunet-service-arm.h
@@ -27,8 +27,17 @@
27#ifndef GNUNET_SERVICE_ARM__H 27#ifndef GNUNET_SERVICE_ARM__H
28#define GNUNET_SERVICE_ARM__H 28#define GNUNET_SERVICE_ARM__H
29 29
30void start_service (struct GNUNET_SERVER_Client *client, 30/**
31 const char *servicename); 31 * Start the specified service.
32 *
33 * @param client who is asking for this
34 * @param servicename name of the service to start
35 * @param lsocks -1 terminated list of listen sockets to pass (systemd style), or NULL
36 * @return GNUNET_OK on success
37 */
38int start_service (struct GNUNET_SERVER_Client *client,
39 const char *servicename,
40 const int *lsocks);
32 41
33/** 42/**
34 * Stop listening for connections to a service. 43 * Stop listening for connections to a service.
diff --git a/src/arm/gnunet-service-arm_interceptor.c b/src/arm/gnunet-service-arm_interceptor.c
index 9380a8deb..bc8db396b 100644
--- a/src/arm/gnunet-service-arm_interceptor.c
+++ b/src/arm/gnunet-service-arm_interceptor.c
@@ -847,7 +847,6 @@ stop_listening (const char *serviceName)
847 return ret; 847 return ret;
848} 848}
849 849
850
851/** 850/**
852 * First connection has come to the listening socket associated with the service, 851 * First connection has come to the listening socket associated with the service,
853 * create the service in order to relay the incoming connection to it 852 * create the service in order to relay the incoming connection to it
@@ -856,14 +855,15 @@ stop_listening (const char *serviceName)
856 * @param tc context 855 * @param tc context
857 */ 856 */
858static void 857static void
859acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 858acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
859
860
861#if MINGW
862static void
863accept_and_forward (struct ServiceListeningInfo *serviceListeningInfo)
860{ 864{
861 struct ServiceListeningInfo *serviceListeningInfo = cls;
862 struct ForwardedConnection *fc; 865 struct ForwardedConnection *fc;
863 866
864 serviceListeningInfo->acceptTask = GNUNET_SCHEDULER_NO_TASK;
865 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
866 return;
867 fc = GNUNET_malloc (sizeof (struct ForwardedConnection)); 867 fc = GNUNET_malloc (sizeof (struct ForwardedConnection));
868 fc->listen_info = serviceListeningInfo; 868 fc->listen_info = serviceListeningInfo;
869 fc->service_to_client_bufferPos = fc->service_to_client_buffer; 869 fc->service_to_client_bufferPos = fc->service_to_client_buffer;
@@ -879,6 +879,9 @@ acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
879 serviceListeningInfo->serviceName, 879 serviceListeningInfo->serviceName,
880 STRERROR (errno)); 880 STRERROR (errno));
881 GNUNET_free (fc); 881 GNUNET_free (fc);
882 GNUNET_CONTAINER_DLL_insert (serviceListeningInfoList_head,
883 serviceListeningInfoList_tail,
884 serviceListeningInfo);
882 serviceListeningInfo->acceptTask = 885 serviceListeningInfo->acceptTask =
883 GNUNET_SCHEDULER_add_read_net (scheduler, 886 GNUNET_SCHEDULER_add_read_net (scheduler,
884 GNUNET_TIME_UNIT_FOREVER_REL, 887 GNUNET_TIME_UNIT_FOREVER_REL,
@@ -889,10 +892,7 @@ acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
889 } 892 }
890 GNUNET_break (GNUNET_OK == 893 GNUNET_break (GNUNET_OK ==
891 GNUNET_NETWORK_socket_close (serviceListeningInfo->listeningSocket)); 894 GNUNET_NETWORK_socket_close (serviceListeningInfo->listeningSocket));
892 GNUNET_CONTAINER_DLL_remove (serviceListeningInfoList_head, 895 start_service (NULL, serviceListeningInfo->serviceName, NULL);
893 serviceListeningInfoList_tail,
894 serviceListeningInfo);
895 start_service (NULL, serviceListeningInfo->serviceName);
896 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 896 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
897 _("Service `%s' started\n"), 897 _("Service `%s' started\n"),
898 fc->listen_info->serviceName); 898 fc->listen_info->serviceName);
@@ -909,6 +909,72 @@ acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
909 &start_forwarding, 909 &start_forwarding,
910 fc); 910 fc);
911} 911}
912#endif
913
914
915/**
916 * First connection has come to the listening socket associated with the service,
917 * create the service in order to relay the incoming connection to it
918 *
919 * @param cls callback data, struct ServiceListeningInfo describing a listen socket
920 * @param tc context
921 */
922static void
923acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
924{
925 struct ServiceListeningInfo *sli = cls;
926 struct ServiceListeningInfo *pos;
927 struct ServiceListeningInfo *next;
928 int *lsocks;
929 unsigned int ls;
930
931 sli->acceptTask = GNUNET_SCHEDULER_NO_TASK;
932 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
933 return;
934 GNUNET_CONTAINER_DLL_remove (serviceListeningInfoList_head,
935 serviceListeningInfoList_tail,
936 sli);
937#ifndef MINGW
938 lsocks = NULL;
939 ls = 0;
940 next = serviceListeningInfoList_head;
941 while (NULL != (pos = next))
942 {
943 next = pos->next;
944 if (0 == strcmp (pos->serviceName,
945 sli->serviceName))
946 {
947 GNUNET_array_append (lsocks, ls,
948 GNUNET_NETWORK_get_fd (pos->listeningSocket));
949 GNUNET_free (pos->listeningSocket); /* deliberately no closing! */
950 GNUNET_free (pos->service_addr);
951 GNUNET_free (pos->serviceName);
952 GNUNET_SCHEDULER_cancel (scheduler,
953 pos->acceptTask);
954 GNUNET_CONTAINER_DLL_remove (serviceListeningInfoList_head,
955 serviceListeningInfoList_tail,
956 pos);
957 GNUNET_free (pos);
958 }
959 }
960 GNUNET_array_append (lsocks, ls,
961 GNUNET_NETWORK_get_fd (sli->listeningSocket));
962 GNUNET_free (sli->listeningSocket); /* deliberately no closing! */
963 GNUNET_free (sli->service_addr);
964 GNUNET_array_append (lsocks, ls, -1);
965 start_service (NULL,
966 sli->serviceName,
967 lsocks);
968 ls = 0;
969 while (lsocks[ls] != -1)
970 GNUNET_break (0 == close (lsocks[ls++]));
971 GNUNET_array_grow (lsocks, ls, 0);
972 GNUNET_free (sli->serviceName);
973 GNUNET_free (sli);
974#else
975 accept_and_forward (sli);
976#endif
977}
912 978
913 979
914/** 980/**
diff --git a/src/include/gnunet_network_lib.h b/src/include/gnunet_network_lib.h
index d7d3acbf0..19fd234ee 100644
--- a/src/include/gnunet_network_lib.h
+++ b/src/include/gnunet_network_lib.h
@@ -199,6 +199,7 @@ int GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
199ssize_t GNUNET_NETWORK_socket_send (const struct GNUNET_NETWORK_Handle *desc, 199ssize_t GNUNET_NETWORK_socket_send (const struct GNUNET_NETWORK_Handle *desc,
200 const void *buffer, size_t length); 200 const void *buffer, size_t length);
201 201
202
202/** 203/**
203 * Send data to a particular destination (always non-blocking). 204 * Send data to a particular destination (always non-blocking).
204 * This function only works for UDP sockets. 205 * This function only works for UDP sockets.
diff --git a/src/include/gnunet_os_lib.h b/src/include/gnunet_os_lib.h
index 3aa1f1bad..87d9a8fb1 100644
--- a/src/include/gnunet_os_lib.h
+++ b/src/include/gnunet_os_lib.h
@@ -216,12 +216,15 @@ GNUNET_OS_start_process (struct GNUNET_DISK_PipeHandle *pipe_stdin,
216/** 216/**
217 * Start a process. 217 * Start a process.
218 * 218 *
219 * @param lsocks array of listen sockets to dup systemd-style (or NULL);
220 * must be NULL on platforms where dup is not supported
219 * @param filename name of the binary 221 * @param filename name of the binary
220 * @param argv NULL-terminated list of arguments to the process, 222 * @param argv NULL-terminated list of arguments to the process,
221 * including the process name as the first argument 223 * including the process name as the first argument
222 * @return process ID of the new process, -1 on error 224 * @return process ID of the new process, -1 on error
223 */ 225 */
224pid_t GNUNET_OS_start_process_v (const char *filename, char *const argv[]); 226pid_t GNUNET_OS_start_process_v (const int *lsocks,
227 const char *filename, char *const argv[]);
225 228
226 229
227/** 230/**
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)