Fix up subprocess docs
[platform/upstream/glib.git] / gio / gsubprocesslauncher.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright © 2012 Red Hat, Inc.
4  * Copyright © 2012-2013 Canonical Limited
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published
8  * by the Free Software Foundation; either version 2 of the licence or (at
9  * your option) any later version.
10  *
11  * See the included COPYING file for more information.
12  *
13  * Authors: Colin Walters <walters@verbum.org>
14  *          Ryan Lortie <desrt@desrt.ca>
15  */
16
17 /**
18  * SECTION:gsubprocesslauncher
19  * @title: GSubprocess Launcher
20  * @short_description: Environment options for launching a child process
21  *
22  * This class contains a set of options for launching child processes,
23  * such as where its standard input and output will be directed, the
24  * argument list, the environment, and more.
25  *
26  * While the #GSubprocess class has high level functions covering
27  * popular cases, use of this class allows access to more advanced
28  * options.  It can also be used to launch multiple subprocesses with
29  * a similar configuration.
30  *
31  * Since: 2.40
32  */
33
34 #define ALL_STDIN_FLAGS         (G_SUBPROCESS_FLAGS_STDIN_PIPE |        \
35                                  G_SUBPROCESS_FLAGS_STDIN_INHERIT)
36 #define ALL_STDOUT_FLAGS        (G_SUBPROCESS_FLAGS_STDOUT_PIPE |       \
37                                  G_SUBPROCESS_FLAGS_STDOUT_SILENCE)
38 #define ALL_STDERR_FLAGS        (G_SUBPROCESS_FLAGS_STDERR_PIPE |       \
39                                  G_SUBPROCESS_FLAGS_STDERR_SILENCE |    \
40                                  G_SUBPROCESS_FLAGS_STDERR_MERGE)
41
42 #include "config.h"
43
44 #include "gsubprocesslauncher-private.h"
45 #include "gioenumtypes.h"
46 #include "gsubprocess.h"
47 #include "ginitable.h"
48
49 #ifdef G_OS_UNIX
50 #include <unistd.h>
51 #include <fcntl.h>
52 #endif
53
54 typedef GObjectClass GSubprocessLauncherClass;
55
56 G_DEFINE_TYPE (GSubprocessLauncher, g_subprocess_launcher, G_TYPE_OBJECT);
57
58 static gboolean
59 verify_disposition (const gchar      *stream_name,
60                     GSubprocessFlags  filtered_flags,
61                     gint              fd,
62                     const gchar      *filename)
63 {
64   guint n_bits;
65
66   if (!filtered_flags)
67     n_bits = 0;
68   else if (((filtered_flags - 1) & filtered_flags) == 0)
69     n_bits = 1;
70   else
71     n_bits = 2; /* ...or more */
72
73   if (n_bits + (fd >= 0) + (filename != NULL) > 1)
74     {
75       GString *err;
76
77       err = g_string_new (NULL);
78       if (n_bits)
79         {
80           GFlagsClass *class;
81           GFlagsValue *value;
82
83           class = g_type_class_peek (G_TYPE_SUBPROCESS_FLAGS);
84           while ((value = g_flags_get_first_value (class, filtered_flags)))
85             {
86               g_string_append_printf (err, " %s", value->value_name);
87               filtered_flags &= value->value;
88             }
89
90           g_type_class_unref (class);
91         }
92
93       if (fd >= 0)
94         g_string_append_printf (err, " g_subprocess_launcher_take_%s_fd()", stream_name);
95
96       if (filename)
97         g_string_append_printf (err, " g_subprocess_launcher_set_%s_file_path()", stream_name);
98
99       g_critical ("You may specify at most one disposition for the %s stream, but you specified:%s.",
100                   stream_name, err->str);
101       g_string_free (err, TRUE);
102
103       return FALSE;
104     }
105
106   return TRUE;
107 }
108
109 static gboolean
110 verify_flags (GSubprocessFlags flags)
111 {
112   return verify_disposition ("stdin", flags & ALL_STDIN_FLAGS, -1, NULL) &&
113          verify_disposition ("stdout", flags & ALL_STDOUT_FLAGS, -1, NULL) &&
114          verify_disposition ("stderr", flags & ALL_STDERR_FLAGS, -1, NULL);
115 }
116
117 static void
118 g_subprocess_launcher_set_property (GObject *object, guint prop_id,
119                                     const GValue *value, GParamSpec *pspec)
120 {
121   GSubprocessLauncher *launcher = G_SUBPROCESS_LAUNCHER (object);
122
123   g_assert (prop_id == 1);
124
125   if (verify_flags (g_value_get_flags (value)))
126     launcher->flags = g_value_get_flags (value);
127 }
128
129 static void
130 g_subprocess_launcher_finalize (GObject *object)
131 {
132   GSubprocessLauncher *self = G_SUBPROCESS_LAUNCHER (object);
133   guint i;
134
135   g_strfreev (self->envp);
136   g_free (self->cwd);
137
138 #ifdef G_OS_UNIX
139   g_free (self->stdin_path);
140   g_free (self->stdout_path);
141   g_free (self->stderr_path);
142
143   if (self->stdin_fd != -1)
144     close (self->stdin_fd);
145
146   if (self->stdout_fd != -1)
147     close (self->stdout_fd);
148
149   if (self->stderr_fd != -1)
150     close (self->stderr_fd);
151
152   if (self->basic_fd_assignments)
153     {
154       for (i = 0; i < self->basic_fd_assignments->len; i++)
155         (void) close (g_array_index (self->basic_fd_assignments, int, i));
156       g_array_unref (self->basic_fd_assignments);
157     }
158   if (self->needdup_fd_assignments)
159     {
160       for (i = 0; i < self->needdup_fd_assignments->len; i += 2)
161         (void) close (g_array_index (self->needdup_fd_assignments, int, i));
162       g_array_unref (self->needdup_fd_assignments);
163     }
164 #endif
165
166   if (self->child_setup_destroy_notify)
167     (* self->child_setup_destroy_notify) (self->child_setup_user_data);
168
169   G_OBJECT_CLASS (g_subprocess_launcher_parent_class)->finalize (object);
170 }
171
172 static void
173 g_subprocess_launcher_init (GSubprocessLauncher  *self)
174 {
175   self->envp = g_listenv ();
176
177   self->stdin_fd = -1;
178   self->stdout_fd = -1;
179   self->stderr_fd = -1;
180 #ifdef G_OS_UNIX
181   self->basic_fd_assignments = g_array_new (FALSE, 0, sizeof (int));
182   self->needdup_fd_assignments = g_array_new (FALSE, 0, sizeof (int));
183 #endif
184 }
185
186 static void
187 g_subprocess_launcher_class_init (GSubprocessLauncherClass *class)
188 {
189   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
190
191   gobject_class->set_property = g_subprocess_launcher_set_property;
192   gobject_class->finalize = g_subprocess_launcher_finalize;
193
194   g_object_class_install_property (gobject_class, 1,
195                                    g_param_spec_flags ("flags", "Flags", "GSubprocessFlags for launched processes",
196                                                        G_TYPE_SUBPROCESS_FLAGS, 0, G_PARAM_WRITABLE |
197                                                        G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY));
198 }
199
200 /**
201  * g_subprocess_launcher_new:
202  * @flags: #GSubprocessFlags
203  *
204  * Creates a new #GSubprocessLauncher.
205  *
206  * The launcher is created with the default options.  A copy of the
207  * environment of the calling process is made at the time of this call
208  * and will be used as the environment that the process is launched in.
209  *
210  * Since: 2.40
211  **/
212 GSubprocessLauncher *
213 g_subprocess_launcher_new (GSubprocessFlags flags)
214 {
215   if (!verify_flags (flags))
216     return NULL;
217
218   return g_object_new (G_TYPE_SUBPROCESS_LAUNCHER,
219                        "flags", flags,
220                        NULL);
221 }
222
223 /**
224  * g_subprocess_launcher_set_environ:
225  * @self: a #GSubprocess
226  * @environ: the replacement environment
227  *
228  * Replace the entire environment of processes launched from this
229  * launcher with the given 'environ' variable.
230  *
231  * Typically you will build this variable by using g_listenv() to copy
232  * the process 'environ' and using the functions g_environ_setenv(),
233  * g_environ_unsetenv(), etc.
234  *
235  * As an alternative, you can use g_subprocess_launcher_setenv(),
236  * g_subprocess_launcher_unsetenv(), etc.
237  *
238  * All strings in this array are expected to be in the GLib file name
239  * encoding.  On UNIX, this means that they can be arbitrary byte
240  * strings.  On Windows, they should be in UTF-8.
241  *
242  * Since: 2.40
243  **/
244 void
245 g_subprocess_launcher_set_environ (GSubprocessLauncher  *self,
246                                    gchar               **environ)
247 {
248   g_strfreev (self->envp);
249   self->envp = g_strdupv (environ);
250 }
251
252 /**
253  * g_subprocess_launcher_setenv:
254  * @self: a #GSubprocess
255  * @variable: the environment variable to set, must not contain '='
256  * @value: the new value for the variable
257  * @overwrite: whether to change the variable if it already exists
258  *
259  * Sets the environment variable @variable in the environment of
260  * processes launched from this launcher.
261  *
262  * Both the variable's name and value should be in the GLib file name
263  * encoding. On UNIX, this means that they can be arbitrary byte
264  * strings. On Windows, they should be in UTF-8.
265  *
266  *
267  * Since: 2.40
268  **/
269 void
270 g_subprocess_launcher_setenv (GSubprocessLauncher *self,
271                               const gchar         *variable,
272                               const gchar         *value,
273                               gboolean             overwrite)
274 {
275   self->envp = g_environ_setenv (self->envp, variable, value, overwrite);
276 }
277
278 /**
279  * g_subprocess_launcher_unsetenv:
280  * @self: a #GSubprocess
281  * @variable: the environment variable to unset, must not contain '='
282  *
283  * Removes the environment variable @variable from the environment of
284  * processes launched from this launcher.
285  *
286  * The variable name should be in the GLib file name encoding.  On UNIX,
287  * this means that they can be arbitrary byte strings.  On Windows, they
288  * should be in UTF-8.
289  *
290  * Since: 2.40
291  **/
292 void
293 g_subprocess_launcher_unsetenv (GSubprocessLauncher *self,
294                                 const gchar         *variable)
295 {
296   self->envp = g_environ_unsetenv (self->envp, variable);
297 }
298
299 /**
300  * g_subprocess_launcher_getenv:
301  * @self: a #GSubprocess
302  * @variable: the environment variable to get
303  *
304  * Returns the value of the environment variable @variable in the
305  * environment of processes launched from this launcher.
306  *
307  * The returned string is in the GLib file name encoding.  On UNIX, this
308  * means that it can be an arbitrary byte string.  On Windows, it will
309  * be UTF-8.
310  *
311  * Returns: the value of the environment variable, %NULL if unset
312  *
313  * Since: 2.40
314  **/
315 const gchar *
316 g_subprocess_launcher_getenv (GSubprocessLauncher *self,
317                               const gchar         *variable)
318 {
319   return g_environ_getenv (self->envp, variable);
320 }
321
322 /**
323  * g_subprocess_launcher_set_cwd:
324  * @self: a #GSubprocess
325  * @cwd: the cwd for launched processes
326  *
327  * Sets the current working directory that processes will be launched
328  * with.
329  *
330  * By default processes are launched with the current working directory
331  * of the launching process at the time of launch.
332  *
333  * Since: 2.40
334  **/
335 void
336 g_subprocess_launcher_set_cwd (GSubprocessLauncher *self,
337                                const gchar         *cwd)
338 {
339   g_free (self->cwd);
340   self->cwd = g_strdup (cwd);
341 }
342
343 /**
344  * g_subprocess_launcher_set_flags:
345  * @self: a #GSubprocessLauncher
346  * @flags: #GSubprocessFlags
347  *
348  * Sets the flags on the launcher.
349  *
350  * The default flags are %G_SUBPROCESS_FLAGS_NONE.
351  *
352  * You may not set flags that specify conflicting options for how to
353  * handle a particular stdio stream (eg: specifying both
354  * %G_SUBPROCESS_FLAGS_STDIN_PIPE and
355  * %G_SUBPROCESS_FLAGS_STDIN_INHERIT).
356  *
357  * You may also not set a flag that conflicts with a previous call to a
358  * function like g_subprocess_launcher_set_stdin_file_path() or
359  * g_subprocess_launcher_take_stdout_fd().
360  *
361  * Since: 2.40
362  **/
363 void
364 g_subprocess_launcher_set_flags (GSubprocessLauncher *self,
365                                  GSubprocessFlags     flags)
366 {
367   if (verify_disposition ("stdin", flags & ALL_STDIN_FLAGS, self->stdin_fd, self->stdin_path) &&
368       verify_disposition ("stdout", flags & ALL_STDOUT_FLAGS, self->stdout_fd, self->stdout_path) &&
369       verify_disposition ("stderr", flags & ALL_STDERR_FLAGS, self->stderr_fd, self->stderr_path))
370     self->flags = flags;
371 }
372
373 #ifdef G_OS_UNIX
374 static void
375 assign_fd (gint *fd_ptr, gint fd)
376 {
377   gint flags;
378
379   if (*fd_ptr != -1)
380     close (*fd_ptr);
381
382   *fd_ptr = fd;
383
384   if (fd != -1)
385     {
386       /* best effort */
387       flags = fcntl (fd, F_GETFD);
388       if (~flags & FD_CLOEXEC)
389         fcntl (fd, F_SETFD, flags | FD_CLOEXEC);
390     }
391 }
392
393 /**
394  * g_subprocess_launcher_set_stdin_file_path:
395  * @self: a #GSubprocessLauncher
396  * @path: a filename or %NULL
397  *
398  * Sets the file path to use as the stdin for spawned processes.
399  *
400  * If @path is %NULL then any previously given path is unset.
401  *
402  * The file must exist or spawning the process will fail.
403  *
404  * You may not set a stdin file path if a stdin fd is already set or if
405  * the launcher flags contain any flags directing stdin elsewhere.
406  *
407  * This feature is only available on UNIX.
408  *
409  * Since: 2.40
410  **/
411 void
412 g_subprocess_launcher_set_stdin_file_path (GSubprocessLauncher *self,
413                                            const gchar         *path)
414 {
415   if (verify_disposition ("stdin", self->flags & ALL_STDIN_FLAGS, self->stdin_fd, path))
416     {
417       g_free (self->stdin_path);
418       self->stdin_path = g_strdup (path);
419     }
420 }
421
422 /**
423  * g_subprocess_launcher_take_stdin_fd:
424  * @self: a #GSubprocessLauncher
425  * @fd: a file descriptor, or -1
426  *
427  * Sets the file descriptor to use as the stdin for spawned processes.
428  *
429  * If @fd is -1 then any previously given fd is unset.
430  *
431  * Note that if your intention is to have the stdin of the calling
432  * process inherited by the child then %G_SUBPROCESS_FLAGS_STDIN_INHERIT
433  * is a better way to go about doing that.
434  *
435  * The passed @fd is noted but will not be touched in the current
436  * process.  It is therefore necessary that it be kept open by the
437  * caller until the subprocess is spawned.  The file descriptor will
438  * also not be explicitly closed on the child side, so it must be marked
439  * O_CLOEXEC if that's what you want.
440  *
441  * You may not set a stdin fd if a stdin file path is already set or if
442  * the launcher flags contain any flags directing stdin elsewhere.
443  *
444  * This feature is only available on UNIX.
445  *
446  * Since: 2.40
447  **/
448 void
449 g_subprocess_launcher_take_stdin_fd (GSubprocessLauncher *self,
450                                      gint                 fd)
451 {
452   if (verify_disposition ("stdin", self->flags & ALL_STDIN_FLAGS, fd, self->stdin_path))
453     assign_fd (&self->stdin_fd, fd);
454 }
455
456 /**
457  * g_subprocess_launcher_set_stdout_file_path:
458  * @self: a #GSubprocessLauncher
459  * @path: a filename or %NULL
460  *
461  * Sets the file path to use as the stdout for spawned processes.
462  *
463  * If @path is %NULL then any previously given path is unset.
464  *
465  * The file will be created or truncated when the process is spawned, as
466  * would be the case if using '>' at the shell.
467  *
468  * You may not set a stdout file path if a stdout fd is already set or
469  * if the launcher flags contain any flags directing stdout elsewhere.
470  *
471  * This feature is only available on UNIX.
472  *
473  * Since: 2.40
474  **/
475 void
476 g_subprocess_launcher_set_stdout_file_path (GSubprocessLauncher *self,
477                                             const gchar         *path)
478 {
479   if (verify_disposition ("stdout", self->flags & ALL_STDOUT_FLAGS, self->stdout_fd, path))
480     {
481       g_free (self->stdout_path);
482       self->stdout_path = g_strdup (path);
483     }
484 }
485
486 /**
487  * g_subprocess_launcher_take_stdout_fd:
488  * @self: a #GSubprocessLauncher
489  * @fd: a file descriptor, or -1
490  *
491  * Sets the file descriptor to use as the stdout for spawned processes.
492  *
493  * If @fd is -1 then any previously given fd is unset.
494  *
495  * Note that the default behaviour is to pass stdout through to the
496  * stdout of the parent process.
497  *
498  * The passed @fd is noted but will not be touched in the current
499  * process.  It is therefore necessary that it be kept open by the
500  * caller until the subprocess is spawned.  The file descriptor will
501  * also not be explicitly closed on the child side, so it must be marked
502  * O_CLOEXEC if that's what you want.
503  *
504  * You may not set a stdout fd if a stdout file path is already set or
505  * if the launcher flags contain any flags directing stdout elsewhere.
506  *
507  * This feature is only available on UNIX.
508  *
509  * Since: 2.40
510  **/
511 void
512 g_subprocess_launcher_take_stdout_fd (GSubprocessLauncher *self,
513                                       gint                 fd)
514 {
515   if (verify_disposition ("stdout", self->flags & ALL_STDOUT_FLAGS, fd, self->stdout_path))
516     assign_fd (&self->stdout_fd, fd);
517 }
518
519 /**
520  * g_subprocess_launcher_set_stderr_file_path:
521  * @self: a #GSubprocessLauncher
522  * @path: a filename or %NULL
523  *
524  * Sets the file path to use as the stderr for spawned processes.
525  *
526  * If @path is %NULL then any previously given path is unset.
527  *
528  * The file will be created or truncated when the process is spawned, as
529  * would be the case if using '2>' at the shell.
530  *
531  * If you want to send both stdout and stderr to the same file then use
532  * %G_SUBPROCESS_FLAGS_STDERR_MERGE.
533  *
534  * You may not set a stderr file path if a stderr fd is already set or
535  * if the launcher flags contain any flags directing stderr elsewhere.
536  *
537  * This feature is only available on UNIX.
538  *
539  * Since: 2.40
540  **/
541 void
542 g_subprocess_launcher_set_stderr_file_path (GSubprocessLauncher *self,
543                                             const gchar         *path)
544 {
545   if (verify_disposition ("stderr", self->flags & ALL_STDERR_FLAGS, self->stderr_fd, path))
546     {
547       g_free (self->stderr_path);
548       self->stderr_path = g_strdup (path);
549     }
550 }
551
552 /**
553  * g_subprocess_launcher_take_stderr_fd:
554  * @self: a #GSubprocessLauncher
555  * @fd: a file descriptor, or -1
556  *
557  * Sets the file descriptor to use as the stderr for spawned processes.
558  *
559  * If @fd is -1 then any previously given fd is unset.
560  *
561  * Note that the default behaviour is to pass stderr through to the
562  * stderr of the parent process.
563  *
564  * The passed @fd belongs to the #GSubprocessLauncher.  It will be
565  * automatically closed when the launcher is finalized.  The file
566  * descriptor will also be closed on the child side when executing the
567  * spawned process.
568  *
569  * You may not set a stderr fd if a stderr file path is already set or
570  * if the launcher flags contain any flags directing stderr elsewhere.
571  *
572  * This feature is only available on UNIX.
573  *
574  * Since: 2.40
575  **/
576 void
577 g_subprocess_launcher_take_stderr_fd (GSubprocessLauncher *self,
578                                      gint                 fd)
579 {
580   if (verify_disposition ("stderr", self->flags & ALL_STDERR_FLAGS, fd, self->stderr_path))
581     assign_fd (&self->stderr_fd, fd);
582 }
583
584 /**
585  * g_subprocess_launcher_take_fd:
586  * @self: a #GSubprocessLauncher
587  * @source_fd: File descriptor in parent process
588  * @target_fd: Target descriptor for child process
589  *
590  * Transfer an arbitrary file descriptor from parent process to the
591  * child.  This function takes "ownership" of the fd; it will be closed
592  * in the parent when @self is freed.
593  *
594  * By default, all file descriptors from the parent will be closed.
595  * This function allows you to create (for example) a custom pipe() or
596  * socketpair() before launching the process, and choose the target
597  * descriptor in the child.
598  *
599  * An example use case is GNUPG, which has a command line argument
600  * --passphrase-fd providing a file descriptor number where it expects
601  * the passphrase to be written.
602  */
603 void
604 g_subprocess_launcher_take_fd (GSubprocessLauncher   *self,
605                                gint                   source_fd,
606                                gint                   target_fd)
607 {
608   if (source_fd == target_fd)
609     {
610       g_array_append_val (self->basic_fd_assignments, source_fd);
611     }
612   else
613     {
614       g_array_append_val (self->needdup_fd_assignments, source_fd);
615       g_array_append_val (self->needdup_fd_assignments, target_fd);
616     }
617 }
618
619 /**
620  * g_subprocess_launcher_set_child_setup:
621  * @self: a #GSubprocessLauncher
622  * @child_setup: a #GSpawnChildSetupFunc to use as the child setup function
623  * @user_data: user data for @child_setup
624  * @destroy_notify: a #GDestroyNotify for @user_data
625  *
626  * Sets up a child setup function.
627  *
628  * The child setup function will be called after fork() but before
629  * exec() on the child's side.
630  *
631  * @destroy_notify will not be automatically called on the child's side
632  * of the fork().  It will only be called when the last reference on the
633  * #GSubprocessLauncher is dropped or when a new child setup function is
634  * given.
635  *
636  * %NULL can be given as @child_setup to disable the functionality.
637  *
638  * Child setup functions are only available on UNIX.
639  *
640  * Since: 2.40
641  **/
642 void
643 g_subprocess_launcher_set_child_setup (GSubprocessLauncher  *self,
644                                        GSpawnChildSetupFunc  child_setup,
645                                        gpointer              user_data,
646                                        GDestroyNotify        destroy_notify)
647 {
648   if (self->child_setup_destroy_notify)
649     (* self->child_setup_destroy_notify) (self->child_setup_user_data);
650
651   self->child_setup_func = child_setup;
652   self->child_setup_user_data = user_data;
653   self->child_setup_destroy_notify = destroy_notify;
654 }
655 #endif
656
657 /**
658  * g_subprocess_launcher_spawn:
659  * @self: a #GSubprocessLauncher
660  * @error: Error
661  * @argv0: Command line arguments
662  * @...: Continued arguments, %NULL terminated
663  *
664  * A convenience helper for creating a #GSubprocess given a provided
665  * varargs list of arguments.
666  *
667  * Since: 2.40
668  * Returns: (transfer full): A new #GSubprocess, or %NULL on error (and @error will be set)
669  **/
670 GSubprocess *
671 g_subprocess_launcher_spawn (GSubprocessLauncher  *launcher,
672                              GError              **error,
673                              const gchar          *argv0,
674                              ...)
675 {
676   GSubprocess *result;
677   GPtrArray *args;
678   const gchar *arg;
679   va_list ap;
680
681   g_return_val_if_fail (argv0 != NULL && argv0[0] != '\0', NULL);
682   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
683
684   args = g_ptr_array_new ();
685
686   va_start (ap, argv0);
687   g_ptr_array_add (args, (gchar *) argv0);
688   while ((arg = va_arg (ap, const gchar *)))
689     g_ptr_array_add (args, (gchar *) arg);
690
691   result = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
692
693   g_ptr_array_free (args, TRUE);
694
695   return result;
696
697 }
698
699 /**
700  * g_subprocess_launcher_spawnv:
701  * @self: a #GSubprocessLauncher
702  * @argv: Command line arguments
703  * @error: Error
704  *
705  * A convenience helper for creating a #GSubprocess given a provided
706  * array of arguments.
707  *
708  * Since: 2.40
709  * Returns: (transfer full): A new #GSubprocess, or %NULL on error (and @error will be set)
710  **/
711 GSubprocess *
712 g_subprocess_launcher_spawnv (GSubprocessLauncher  *launcher,
713                               const gchar * const  *argv,
714                               GError              **error)
715 {
716   GSubprocess *subprocess;
717
718   g_return_val_if_fail (argv != NULL && argv[0] != NULL && argv[0][0] != '\0', NULL);
719
720   subprocess = g_object_new (G_TYPE_SUBPROCESS,
721                              "argv", argv,
722                              "flags", launcher->flags,
723                              NULL);
724   g_subprocess_set_launcher (subprocess, launcher);
725
726   if (!g_initable_init (G_INITABLE (subprocess), NULL, error))
727     {
728       g_object_unref (subprocess);
729       return NULL;
730     }
731
732   return subprocess;
733 }