aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2013-11-29 10:25:47 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2013-11-29 10:25:47 +0000
commitd5f83fb8b9a2ae2797b7b0e46bf6cd346743f4b3 (patch)
treea9afdf6ba9fcc2051a5043b061ea9dc86779fb9f /src
parentb0c50f22c52535650a7288c32a3ae3ed6336c32f (diff)
downloadgnunet-d5f83fb8b9a2ae2797b7b0e46bf6cd346743f4b3.tar.gz
gnunet-d5f83fb8b9a2ae2797b7b0e46bf6cd346743f4b3.zip
- move do_start_process to util/
Diffstat (limited to 'src')
-rw-r--r--src/arm/arm_api.c30
-rw-r--r--src/arm/do_start_process.c155
-rw-r--r--src/arm/gnunet-service-arm.c31
-rw-r--r--src/include/gnunet_os_lib.h27
-rw-r--r--src/testing/testing.c20
-rw-r--r--src/util/os_priority.c139
6 files changed, 206 insertions, 196 deletions
diff --git a/src/arm/arm_api.c b/src/arm/arm_api.c
index d27b6b780..7e6ce1870 100644
--- a/src/arm/arm_api.c
+++ b/src/arm/arm_api.c
@@ -737,9 +737,6 @@ control_message_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *t
737} 737}
738 738
739 739
740#include "do_start_process.c"
741
742
743/** 740/**
744 * A client specifically requested starting of ARM itself. 741 * A client specifically requested starting of ARM itself.
745 * This function is called with information about whether 742 * This function is called with information about whether
@@ -832,26 +829,27 @@ arm_service_report (void *cls,
832 /* Means we are ONLY running locally */ 829 /* Means we are ONLY running locally */
833 /* we're clearly running a test, don't daemonize */ 830 /* we're clearly running a test, don't daemonize */
834 if (NULL == config) 831 if (NULL == config)
835 proc = do_start_process (GNUNET_NO, cm->std_inheritance, 832 proc = GNUNET_OS_start_process_s (GNUNET_NO, cm->std_inheritance,
836 NULL, loprefix, quotedbinary, 833 NULL, loprefix, quotedbinary,
837 /* no daemonization! */ 834 /* no daemonization! */
838 lopostfix, NULL); 835 lopostfix, NULL);
839 else 836 else
840 proc = do_start_process (GNUNET_NO, cm->std_inheritance, 837 proc = GNUNET_OS_start_process_s (GNUNET_NO, cm->std_inheritance,
841 NULL, loprefix, quotedbinary, "-c", config, 838 NULL, loprefix, quotedbinary, "-c", config,
842 /* no daemonization! */ 839 /* no daemonization! */
843 lopostfix, NULL); 840 lopostfix, NULL);
844 } 841 }
845 else 842 else
846 { 843 {
847 if (NULL == config) 844 if (NULL == config)
848 proc = do_start_process (GNUNET_NO, cm->std_inheritance, 845 proc = GNUNET_OS_start_process_s (GNUNET_NO, cm->std_inheritance,
849 NULL, loprefix, quotedbinary, 846 NULL, loprefix, quotedbinary,
850 "-d", lopostfix, NULL); 847 "-d", lopostfix, NULL);
851 else 848 else
852 proc = do_start_process (GNUNET_NO, cm->std_inheritance, 849 proc = GNUNET_OS_start_process_s (GNUNET_NO, cm->std_inheritance,
853 NULL, loprefix, quotedbinary, "-c", config, 850 NULL, loprefix, quotedbinary, "-c",
854 "-d", lopostfix, NULL); 851 config,
852 "-d", lopostfix, NULL);
855 } 853 }
856 GNUNET_free (binary); 854 GNUNET_free (binary);
857 GNUNET_free (quotedbinary); 855 GNUNET_free (quotedbinary);
diff --git a/src/arm/do_start_process.c b/src/arm/do_start_process.c
deleted file mode 100644
index 3ff6eba52..000000000
--- a/src/arm/do_start_process.c
+++ /dev/null
@@ -1,155 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2011, 2012 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21#include "gnunet_os_lib.h"
22
23/**
24 * Actually start a process. All of the arguments given to this
25 * function are strings that are used for the "argv" array. However,
26 * if those strings contain spaces, the given argument is split into
27 * multiple argv entries without spaces. Similarly, if an argument is
28 * the empty string, it is skipped. This function has the inherent
29 * limitation that it does NOT allow passing command line arguments
30 * with spaces to the new process.
31 *
32 * @param pipe_control should a pipe be used to send signals to the child?
33 * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags
34 * @param lsocks array of listen sockets to dup starting at fd3 (systemd-style), or NULL
35 * @param first_arg first argument for argv (may be an empty string)
36 * @param ... more arguments, NULL terminated
37 * @return handle of the started process, NULL on error
38 */
39static struct GNUNET_OS_Process *
40do_start_process (int pipe_control, unsigned int std_inheritance,
41 const SOCKTYPE * lsocks, const char *first_arg, ...)
42{
43 va_list ap;
44 char **argv;
45 unsigned int argv_size;
46 const char *arg;
47 const char *rpos;
48 char *pos;
49 char *cp;
50 const char *last;
51 struct GNUNET_OS_Process *proc;
52 char *binary_path;
53 int quote_on;
54 unsigned int i;
55 size_t len;
56
57 argv_size = 1;
58 va_start (ap, first_arg);
59 arg = first_arg;
60 last = NULL;
61 do
62 {
63 rpos = arg;
64 quote_on = 0;
65 while ('\0' != *rpos)
66 {
67 if ('"' == *rpos)
68 {
69 if (1 == quote_on)
70 quote_on = 0;
71 else
72 quote_on = 1;
73 }
74 if ( (' ' == *rpos) && (0 == quote_on) )
75 {
76 if (NULL != last)
77 argv_size++;
78 last = NULL;
79 rpos++;
80 while (' ' == *rpos)
81 rpos++;
82 }
83 if ( (NULL == last) && ('\0' != *rpos) ) // FIXME: == or !=?
84 last = rpos;
85 if ('\0' != *rpos)
86 rpos++;
87 }
88 if (NULL != last)
89 argv_size++;
90 }
91 while (NULL != (arg = (va_arg (ap, const char*))));
92 va_end (ap);
93
94 argv = GNUNET_malloc (argv_size * sizeof (char *));
95 argv_size = 0;
96 va_start (ap, first_arg);
97 arg = first_arg;
98 last = NULL;
99 do
100 {
101 cp = GNUNET_strdup (arg);
102 quote_on = 0;
103 pos = cp;
104 while ('\0' != *pos)
105 {
106 if ('"' == *pos)
107 {
108 if (1 == quote_on)
109 quote_on = 0;
110 else
111 quote_on = 1;
112 }
113 if ( (' ' == *pos) && (0 == quote_on) )
114 {
115 *pos = '\0';
116 if (NULL != last)
117 argv[argv_size++] = GNUNET_strdup (last);
118 last = NULL;
119 pos++;
120 while (' ' == *pos)
121 pos++;
122 }
123 if ( (NULL == last) && ('\0' != *pos)) // FIXME: == or !=?
124 last = pos;
125 if ('\0' != *pos)
126 pos++;
127 }
128 if (NULL != last)
129 argv[argv_size++] = GNUNET_strdup (last);
130 last = NULL;
131 GNUNET_free (cp);
132 }
133 while (NULL != (arg = (va_arg (ap, const char*))));
134 va_end (ap);
135 argv[argv_size] = NULL;
136
137 for(i = 0; i < argv_size; i++)
138 {
139 len = strlen (argv[i]);
140 if ( (argv[i][0] == '"') && (argv[i][len-1] == '"'))
141 {
142 memmove (&argv[i][0], &argv[i][1], len - 2);
143 argv[i][len-2] = '\0';
144 }
145 }
146 binary_path = argv[0];
147 proc = GNUNET_OS_start_process_v (pipe_control, std_inheritance, lsocks,
148 binary_path, argv);
149 while (argv_size > 0)
150 GNUNET_free (argv[--argv_size]);
151 GNUNET_free (argv);
152 return proc;
153}
154
155/* end of do_start_process.c */
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c
index dcc9cf352..b30e8542e 100644
--- a/src/arm/gnunet-service-arm.c
+++ b/src/arm/gnunet-service-arm.c
@@ -246,8 +246,6 @@ static struct GNUNET_SERVER_Handle *server;
246static struct GNUNET_SERVER_NotificationContext *notifier; 246static struct GNUNET_SERVER_NotificationContext *notifier;
247 247
248 248
249#include "do_start_process.c"
250
251/** 249/**
252 * Transmit a status result message. 250 * Transmit a status result message.
253 * 251 *
@@ -496,27 +494,32 @@ start_process (struct ServiceList *sl,
496 { 494 {
497 if (NULL == sl->config) 495 if (NULL == sl->config)
498 sl->proc = 496 sl->proc =
499 do_start_process (sl->pipe_control, GNUNET_OS_INHERIT_STD_OUT_AND_ERR, 497 GNUNET_OS_start_process_s (sl->pipe_control,
500 lsocks, loprefix, quotedbinary, "-L", 498 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
501 "DEBUG", options, NULL); 499 lsocks, loprefix, quotedbinary, "-L",
500 "DEBUG", options, NULL);
502 else 501 else
503 sl->proc = 502 sl->proc =
504 do_start_process (sl->pipe_control, GNUNET_OS_INHERIT_STD_OUT_AND_ERR, 503 GNUNET_OS_start_process_s (sl->pipe_control,
505 lsocks, loprefix, quotedbinary, "-c", sl->config, "-L", 504 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
506 "DEBUG", options, NULL); 505 lsocks, loprefix, quotedbinary, "-c",
506 sl->config, "-L",
507 "DEBUG", options, NULL);
507 } 508 }
508 else 509 else
509 { 510 {
510 if (NULL == sl->config) 511 if (NULL == sl->config)
511 sl->proc = 512 sl->proc =
512 do_start_process (sl->pipe_control, GNUNET_OS_INHERIT_STD_OUT_AND_ERR, 513 GNUNET_OS_start_process_s (sl->pipe_control,
513 lsocks, loprefix, quotedbinary, 514 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
514 options, NULL); 515 lsocks, loprefix, quotedbinary,
516 options, NULL);
515 else 517 else
516 sl->proc = 518 sl->proc =
517 do_start_process (sl->pipe_control, GNUNET_OS_INHERIT_STD_OUT_AND_ERR, 519 GNUNET_OS_start_process_s (sl->pipe_control,
518 lsocks, loprefix, quotedbinary, "-c", sl->config, 520 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
519 options, NULL); 521 lsocks, loprefix, quotedbinary, "-c",
522 sl->config, options, NULL);
520 } 523 }
521 GNUNET_free (binary); 524 GNUNET_free (binary);
522 GNUNET_free (quotedbinary); 525 GNUNET_free (quotedbinary);
diff --git a/src/include/gnunet_os_lib.h b/src/include/gnunet_os_lib.h
index 2944f8dfb..5a81fba6f 100644
--- a/src/include/gnunet_os_lib.h
+++ b/src/include/gnunet_os_lib.h
@@ -381,6 +381,33 @@ GNUNET_OS_start_process_v (int pipe_control,
381 381
382 382
383/** 383/**
384 * Start a process. This function is similar to the GNUNET_OS_start_process_*
385 * except that the @a filename and @argv can have whole strings which contain
386 * the arguments. These arguments are to be separated by spaces and are parsed
387 * in the order they appear. Arguments containing spaces can be used by
388 * quoting them with @em ".
389 *
390 * @param pipe_control should a pipe be used to send signals to the child?
391 * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags
392 * @param lsocks array of listen sockets to dup systemd-style (or NULL);
393 * must be NULL on platforms where dup is not supported
394 * @param filename name of the binary. It is valid to have the arguments
395 * in this string when they are separated by spaces.
396 * @param ... more arguments. Should be of type <tt>char *</tt>. It is valid
397 * to have the arguments in these strings when they are separated by
398 * spaces.
399 * @param argv NULL-terminated list of arguments to the process,
400 * including the process name as the first argument
401 * @return pointer to process structure of the new process, NULL on error
402 */
403struct GNUNET_OS_Process *
404GNUNET_OS_start_process_s (int pipe_control,
405 unsigned int std_inheritance,
406 const SOCKTYPE * lsocks,
407 const char *first_arg, ...);
408
409
410/**
384 * Handle to a command action. 411 * Handle to a command action.
385 */ 412 */
386struct GNUNET_OS_CommandHandle; 413struct GNUNET_OS_CommandHandle;
diff --git a/src/testing/testing.c b/src/testing/testing.c
index 9d54b4c53..62f9cb1a3 100644
--- a/src/testing/testing.c
+++ b/src/testing/testing.c
@@ -34,8 +34,6 @@
34#include "gnunet_arm_service.h" 34#include "gnunet_arm_service.h"
35#include "gnunet_testing_lib.h" 35#include "gnunet_testing_lib.h"
36 36
37#include "../arm/do_start_process.c"
38
39#define LOG(kind,...) \ 37#define LOG(kind,...) \
40 GNUNET_log_from (kind, "testing-api", __VA_ARGS__) 38 GNUNET_log_from (kind, "testing-api", __VA_ARGS__)
41 39
@@ -1254,7 +1252,6 @@ GNUNET_TESTING_peer_configure (struct GNUNET_TESTING_System *system,
1254 } 1252 }
1255 else 1253 else
1256 { 1254 {
1257 peer->main_binary = GNUNET_CONFIGURATION_expand_dollar (peer->cfg, peer->main_binary);
1258 peer->args = strdup (libexec_binary); 1255 peer->args = strdup (libexec_binary);
1259 } 1256 }
1260 peer->system = system; 1257 peer->system = system;
@@ -1325,14 +1322,15 @@ GNUNET_TESTING_peer_start (struct GNUNET_TESTING_Peer *peer)
1325 return GNUNET_SYSERR; 1322 return GNUNET_SYSERR;
1326 i->n_refs++; 1323 i->n_refs++;
1327 } 1324 }
1328 peer->main_process = do_start_process (PIPE_CONTROL, 1325 peer->main_binary = GNUNET_CONFIGURATION_expand_dollar (peer->cfg, peer->main_binary);
1329 GNUNET_OS_INHERIT_STD_OUT_AND_ERR, 1326 peer->main_process = GNUNET_OS_start_process_s (PIPE_CONTROL,
1330 NULL, 1327 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
1331 peer->main_binary, 1328 NULL,
1332 peer->args, 1329 peer->main_binary,
1333 "-c", 1330 peer->args,
1334 peer->cfgfile, 1331 "-c",
1335 NULL); 1332 peer->cfgfile,
1333 NULL);
1336 if (NULL == peer->main_process) 1334 if (NULL == peer->main_process)
1337 { 1335 {
1338 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1336 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
diff --git a/src/util/os_priority.c b/src/util/os_priority.c
index d772e3c87..0f2acca06 100644
--- a/src/util/os_priority.c
+++ b/src/util/os_priority.c
@@ -1329,6 +1329,145 @@ GNUNET_OS_start_process_v (int pipe_control,
1329 1329
1330 1330
1331/** 1331/**
1332 * Start a process. This function is similar to the GNUNET_OS_start_process_*
1333 * except that the @a filename and @argv can have whole strings which contain
1334 * the arguments. These arguments are to be separated by spaces and are parsed
1335 * in the order they appear. Arguments containing spaces can be used by
1336 * quoting them with @em ".
1337 *
1338 * @param pipe_control should a pipe be used to send signals to the child?
1339 * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags
1340 * @param lsocks array of listen sockets to dup systemd-style (or NULL);
1341 * must be NULL on platforms where dup is not supported
1342 * @param filename name of the binary. It is valid to have the arguments
1343 * in this string when they are separated by spaces.
1344 * @param ... more arguments. Should be of type <tt>char *</tt>. It is valid
1345 * to have the arguments in these strings when they are separated by
1346 * spaces.
1347 * @param argv NULL-terminated list of arguments to the process,
1348 * including the process name as the first argument
1349 * @return pointer to process structure of the new process, NULL on error
1350 */
1351struct GNUNET_OS_Process *
1352GNUNET_OS_start_process_s (int pipe_control,
1353 unsigned int std_inheritance,
1354 const SOCKTYPE * lsocks,
1355 const char *first_arg, ...)
1356{
1357 va_list ap;
1358 char **argv;
1359 unsigned int argv_size;
1360 const char *arg;
1361 const char *rpos;
1362 char *pos;
1363 char *cp;
1364 const char *last;
1365 struct GNUNET_OS_Process *proc;
1366 char *binary_path;
1367 int quote_on;
1368 unsigned int i;
1369 size_t len;
1370
1371 argv_size = 1;
1372 va_start (ap, first_arg);
1373 arg = first_arg;
1374 last = NULL;
1375 do
1376 {
1377 rpos = arg;
1378 quote_on = 0;
1379 while ('\0' != *rpos)
1380 {
1381 if ('"' == *rpos)
1382 {
1383 if (1 == quote_on)
1384 quote_on = 0;
1385 else
1386 quote_on = 1;
1387 }
1388 if ( (' ' == *rpos) && (0 == quote_on) )
1389 {
1390 if (NULL != last)
1391 argv_size++;
1392 last = NULL;
1393 rpos++;
1394 while (' ' == *rpos)
1395 rpos++;
1396 }
1397 if ( (NULL == last) && ('\0' != *rpos) ) // FIXME: == or !=?
1398 last = rpos;
1399 if ('\0' != *rpos)
1400 rpos++;
1401 }
1402 if (NULL != last)
1403 argv_size++;
1404 }
1405 while (NULL != (arg = (va_arg (ap, const char*))));
1406 va_end (ap);
1407
1408 argv = GNUNET_malloc (argv_size * sizeof (char *));
1409 argv_size = 0;
1410 va_start (ap, first_arg);
1411 arg = first_arg;
1412 last = NULL;
1413 do
1414 {
1415 cp = GNUNET_strdup (arg);
1416 quote_on = 0;
1417 pos = cp;
1418 while ('\0' != *pos)
1419 {
1420 if ('"' == *pos)
1421 {
1422 if (1 == quote_on)
1423 quote_on = 0;
1424 else
1425 quote_on = 1;
1426 }
1427 if ( (' ' == *pos) && (0 == quote_on) )
1428 {
1429 *pos = '\0';
1430 if (NULL != last)
1431 argv[argv_size++] = GNUNET_strdup (last);
1432 last = NULL;
1433 pos++;
1434 while (' ' == *pos)
1435 pos++;
1436 }
1437 if ( (NULL == last) && ('\0' != *pos)) // FIXME: == or !=?
1438 last = pos;
1439 if ('\0' != *pos)
1440 pos++;
1441 }
1442 if (NULL != last)
1443 argv[argv_size++] = GNUNET_strdup (last);
1444 last = NULL;
1445 GNUNET_free (cp);
1446 }
1447 while (NULL != (arg = (va_arg (ap, const char*))));
1448 va_end (ap);
1449 argv[argv_size] = NULL;
1450
1451 for(i = 0; i < argv_size; i++)
1452 {
1453 len = strlen (argv[i]);
1454 if ( (argv[i][0] == '"') && (argv[i][len-1] == '"'))
1455 {
1456 memmove (&argv[i][0], &argv[i][1], len - 2);
1457 argv[i][len-2] = '\0';
1458 }
1459 }
1460 binary_path = argv[0];
1461 proc = GNUNET_OS_start_process_v (pipe_control, std_inheritance, lsocks,
1462 binary_path, argv);
1463 while (argv_size > 0)
1464 GNUNET_free (argv[--argv_size]);
1465 GNUNET_free (argv);
1466 return proc;
1467}
1468
1469
1470/**
1332 * Retrieve the status of a process, waiting on him if dead. 1471 * Retrieve the status of a process, waiting on him if dead.
1333 * Nonblocking version. 1472 * Nonblocking version.
1334 * 1473 *