Add missing include
[oweals/gnunet.git] / src / arm / do_start_process.c
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  */
39 static struct GNUNET_OS_Process *
40 do_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
54   argv_size = 1;
55   va_start (ap, first_arg);
56   arg = first_arg;
57   last = NULL;
58 /* *INDENT-OFF* */
59   do
60     {
61 /* *INDENT-ON* */
62   rpos = arg;
63   while ('\0' != *rpos)
64     {
65       if (' ' == *rpos)
66         {
67           if (last != NULL)
68             argv_size++;
69           last = NULL;
70           while (' ' == *rpos)
71             rpos++;
72         }
73       if ((last == NULL) && (*rpos != '\0'))
74         last = rpos;
75       if (*rpos != '\0')
76         rpos++;
77     }
78   if (last != NULL)
79     argv_size++;
80 /* *INDENT-OFF* */
81     }
82   while (NULL != (arg = (va_arg (ap, const char*))));
83 /* *INDENT-ON* */
84   va_end (ap);
85
86   argv = GNUNET_malloc (argv_size * sizeof (char *));
87   argv_size = 0;
88   va_start (ap, first_arg);
89   arg = first_arg;
90   last = NULL;
91 /* *INDENT-OFF* */
92   do
93     {
94 /* *INDENT-ON* */
95   cp = GNUNET_strdup (arg);
96   pos = cp;
97   while ('\0' != *pos)
98     {
99       if (' ' == *pos)
100         {
101           *pos = '\0';
102           if (last != NULL)
103             argv[argv_size++] = GNUNET_strdup (last);
104           last = NULL;
105           pos++;
106           while (' ' == *pos)
107             pos++;
108         }
109       if ((last == NULL) && (*pos != '\0'))
110         last = pos;
111       if (*pos != '\0')
112         pos++;
113     }
114   if (last != NULL)
115     argv[argv_size++] = GNUNET_strdup (last);
116   last = NULL;
117   GNUNET_free (cp);
118 /* *INDENT-OFF* */
119     }
120   while (NULL != (arg = (va_arg (ap, const char*))));
121 /* *INDENT-ON* */
122   va_end (ap);
123   argv[argv_size] = NULL;
124   binary_path = argv[0];
125   proc = GNUNET_OS_start_process_v (pipe_control, std_inheritance, lsocks,
126                                     binary_path, argv);
127   while (argv_size > 0)
128     GNUNET_free (argv[--argv_size]);
129   GNUNET_free (argv);
130   return proc;
131 }
132
133 /* end of do_start_process.c */