e8e2ad2376713dcbff26551295e9a722cc4cf6dc
[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:gsubprocess
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
134   g_strfreev (self->envp);
135   g_free (self->cwd);
136
137 #ifdef G_OS_UNIX
138   g_free (self->stdin_path);
139   g_free (self->stdout_path);
140   g_free (self->stderr_path);
141
142   if (self->stdin_fd != -1)
143     close (self->stdin_fd);
144
145   if (self->stdout_fd != -1)
146     close (self->stdout_fd);
147
148   if (self->stderr_fd != -1)
149     close (self->stderr_fd);
150
151   g_clear_pointer (&self->basic_fd_assignments, g_array_unref);
152   g_clear_pointer (&self->needdup_fd_assignments, g_array_unref);
153 #endif
154
155   if (self->child_setup_destroy_notify)
156     (* self->child_setup_destroy_notify) (self->child_setup_user_data);
157
158   G_OBJECT_CLASS (g_subprocess_launcher_parent_class)->finalize (object);
159 }
160
161 static void
162 g_subprocess_launcher_init (GSubprocessLauncher  *self)
163 {
164   self->envp = g_listenv ();
165
166   self->stdin_fd = -1;
167   self->stdout_fd = -1;
168   self->stderr_fd = -1;
169 #ifdef G_OS_UNIX
170   self->basic_fd_assignments = g_array_new (FALSE, 0, sizeof (int));
171   self->needdup_fd_assignments = g_array_new (FALSE, 0, sizeof (int));
172 #endif
173 }
174
175 static void
176 g_subprocess_launcher_class_init (GSubprocessLauncherClass *class)
177 {
178   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
179
180   gobject_class->set_property = g_subprocess_launcher_set_property;
181   gobject_class->finalize = g_subprocess_launcher_finalize;
182
183   g_object_class_install_property (gobject_class, 1,
184                                    g_param_spec_flags ("flags", "Flags", "GSubprocessFlags for launched processes",
185                                                        G_TYPE_SUBPROCESS_FLAGS, 0, G_PARAM_WRITABLE |
186                                                        G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY));
187 }
188
189 /**
190  * g_subprocess_launcher_new:
191  *
192  * Creates a new #GSubprocessLauncher.
193  *
194  * The launcher is created with the default options.  A copy of the
195  * environment of the calling process is made at the time of this call
196  * and will be used as the environment that the process is launched in.
197  *
198  * Since: 2.40
199  **/
200 GSubprocessLauncher *
201 g_subprocess_launcher_new (GSubprocessFlags flags)
202 {
203   if (!verify_flags (flags))
204     return NULL;
205
206   return g_object_new (G_TYPE_SUBPROCESS_LAUNCHER,
207                        "flags", flags,
208                        NULL);
209 }
210
211 /**
212  * g_subprocess_launcher_set_environ:
213  * @self: a #GSubprocess
214  * @environ: the replacement environment
215  *
216  * Replace the entire environment of processes launched from this
217  * launcher with the given 'environ' variable.
218  *
219  * Typically you will build this variable by using g_listenv() to copy
220  * the process 'environ' and using the functions g_environ_setenv(),
221  * g_environ_unsetenv(), etc.
222  *
223  * As an alternative, you can use g_subprocess_launcher_setenv(),
224  * g_subprocess_launcher_unsetenv(), etc.
225  *
226  * All strings in this array are expected to be in the GLib file name
227  * encoding.  On UNIX, this means that they can be arbitrary byte
228  * strings.  On Windows, they should be in UTF-8.
229  *
230  * Since: 2.40
231  **/
232 void
233 g_subprocess_launcher_set_environ (GSubprocessLauncher  *self,
234                                    gchar               **environ)
235 {
236   g_strfreev (self->envp);
237   self->envp = g_strdupv (environ);
238 }
239
240 /**
241  * g_subprocess_launcher_setenv:
242  * @self: a #GSubprocess
243  * @variable: the environment variable to set, must not contain '='
244  * @value: the new value for the variable
245  * @overwrite: whether to change the variable if it already exists
246  *
247  * Sets the environment variable @variable in the environment of
248  * processes launched from this launcher.
249  *
250  * Both the variable's name and value should be in the GLib file name
251  * encoding. On UNIX, this means that they can be arbitrary byte
252  * strings. On Windows, they should be in UTF-8.
253  *
254  *
255  * Since: 2.40
256  **/
257 void
258 g_subprocess_launcher_setenv (GSubprocessLauncher *self,
259                               const gchar         *variable,
260                               const gchar         *value,
261                               gboolean             overwrite)
262 {
263   self->envp = g_environ_setenv (self->envp, variable, value, overwrite);
264 }
265
266 /**
267  * g_subprocess_launcher_unsetsenv:
268  * @self: a #GSubprocess
269  * @variable: the environment variable to unset, must not contain '='
270  *
271  * Removes the environment variable @variable from the environment of
272  * processes launched from this launcher.
273  *
274  * The variable name should be in the GLib file name encoding.  On UNIX,
275  * this means that they can be arbitrary byte strings.  On Windows, they
276  * should be in UTF-8.
277  *
278  * Since: 2.40
279  **/
280 void
281 g_subprocess_launcher_unsetenv (GSubprocessLauncher *self,
282                                 const gchar         *variable)
283 {
284   self->envp = g_environ_unsetenv (self->envp, variable);
285 }
286
287 /**
288  * g_subprocess_launcher_getenv:
289  * @self: a #GSubprocess
290  * @variable: the environment variable to get
291  *
292  * Returns the value of the environment variable @variable in the
293  * environment of processes launched from this launcher.
294  *
295  * The returned string is in the GLib file name encoding.  On UNIX, this
296  * means that it can be an arbitrary byte string.  On Windows, it will
297  * be UTF-8.
298  *
299  * Returns: the value of the environment variable, %NULL if unset
300  *
301  * Since: 2.40
302  **/
303 const gchar *
304 g_subprocess_launcher_getenv (GSubprocessLauncher *self,
305                               const gchar         *variable)
306 {
307   return g_environ_getenv (self->envp, variable);
308 }
309
310 /**
311  * g_subprocess_launcher_set_cwd:
312  * @self: a #GSubprocess
313  * @cwd: the cwd for launched processes
314  *
315  * Sets the current working directory that processes will be launched
316  * with.
317  *
318  * By default processes are launched with the current working directory
319  * of the launching process at the time of launch.
320  *
321  * Since: 2.40
322  **/
323 void
324 g_subprocess_launcher_set_cwd (GSubprocessLauncher *self,
325                                const gchar         *cwd)
326 {
327   g_free (self->cwd);
328   self->cwd = g_strdup (cwd);
329 }
330
331 /**
332  * g_subprocess_launcher_set_flags:
333  * @self: a #GSubprocessLauncher
334  * @flags: #GSubprocessFlags
335  *
336  * Sets the flags on the launcher.
337  *
338  * The default flags are %G_SUBPROCESS_FLAGS_NONE.
339  *
340  * You may not set flags that specify conflicting options for how to
341  * handle a particular stdio stream (eg: specifying both
342  * %G_SUBPROCESS_FLAGS_STDIN_PIPE and
343  * %G_SUBPROCESS_FLAGS_STDIN_INHERIT).
344  *
345  * You may also not set a flag that conflicts with a previous call to a
346  * function like g_subprocess_launcher_set_stdin_file_path() or
347  * g_subprocess_launcher_take_stdout_fd().
348  *
349  * Since: 2.40
350  **/
351 void
352 g_subprocess_launcher_set_flags (GSubprocessLauncher *self,
353                                  GSubprocessFlags     flags)
354 {
355   if (verify_disposition ("stdin", flags & ALL_STDIN_FLAGS, self->stdin_fd, self->stdin_path) &&
356       verify_disposition ("stdout", flags & ALL_STDOUT_FLAGS, self->stdout_fd, self->stdout_path) &&
357       verify_disposition ("stderr", flags & ALL_STDERR_FLAGS, self->stderr_fd, self->stderr_path))
358     self->flags = flags;
359 }
360
361 #ifdef G_OS_UNIX
362 static void
363 assign_fd (gint *fd_ptr, gint fd)
364 {
365   gint flags;
366
367   if (*fd_ptr != -1)
368     close (*fd_ptr);
369
370   *fd_ptr = fd;
371
372   if (fd != -1)
373     {
374       /* best effort */
375       flags = fcntl (fd, F_GETFD);
376       if (~flags & FD_CLOEXEC)
377         fcntl (fd, F_SETFD, flags | FD_CLOEXEC);
378     }
379 }
380
381 /**
382  * g_subprocess_launcher_set_stdin_file_path:
383  * @self: a #GSubprocessLauncher
384  * @path: a filename or %NULL
385  *
386  * Sets the file path to use as the stdin for spawned processes.
387  *
388  * If @path is %NULL then any previously given path is unset.
389  *
390  * The file must exist or spawning the process will fail.
391  *
392  * You may not set a stdin file path if a stdin fd is already set or if
393  * the launcher flags contain any flags directing stdin elsewhere.
394  *
395  * This feature is only available on UNIX.
396  *
397  * Since: 2.40
398  **/
399 void
400 g_subprocess_launcher_set_stdin_file_path (GSubprocessLauncher *self,
401                                            const gchar         *path)
402 {
403   if (verify_disposition ("stdin", self->flags & ALL_STDIN_FLAGS, self->stdin_fd, path))
404     {
405       g_free (self->stdin_path);
406       self->stdin_path = g_strdup (path);
407     }
408 }
409
410 /**
411  * g_subprocess_launcher_take_stdin_fd:
412  * @self: a #GSubprocessLauncher
413  * @fd: a file descriptor, or -1
414  *
415  * Sets the file descriptor to use as the stdin for spawned processes.
416  *
417  * If @fd is -1 then any previously given fd is unset.
418  *
419  * Note that if your intention is to have the stdin of the calling
420  * process inherited by the child then %G_SUBPROCESS_FLAGS_STDIN_INHERIT
421  * is a better way to go about doing that.
422  *
423  * The passed @fd is noted but will not be touched in the current
424  * process.  It is therefore necessary that it be kept open by the
425  * caller until the subprocess is spawned.  The file descriptor will
426  * also not be explicitly closed on the child side, so it must be marked
427  * O_CLOEXEC if that's what you want.
428  *
429  * You may not set a stdin fd if a stdin file path is already set or if
430  * the launcher flags contain any flags directing stdin elsewhere.
431  *
432  * This feature is only available on UNIX.
433  *
434  * Since: 2.40
435  **/
436 void
437 g_subprocess_launcher_take_stdin_fd (GSubprocessLauncher *self,
438                                      gint                 fd)
439 {
440   if (verify_disposition ("stdin", self->flags & ALL_STDIN_FLAGS, fd, self->stdin_path))
441     assign_fd (&self->stdin_fd, fd);
442 }
443
444 /**
445  * g_subprocess_launcher_set_stdout_file_path:
446  * @self: a #GSubprocessLauncher
447  * @path: a filename or %NULL
448  *
449  * Sets the file path to use as the stdout for spawned processes.
450  *
451  * If @path is %NULL then any previously given path is unset.
452  *
453  * The file will be created or truncated when the process is spawned, as
454  * would be the case if using '>' at the shell.
455  *
456  * You may not set a stdout file path if a stdout fd is already set or
457  * if the launcher flags contain any flags directing stdout elsewhere.
458  *
459  * This feature is only available on UNIX.
460  *
461  * Since: 2.40
462  **/
463 void
464 g_subprocess_launcher_set_stdout_file_path (GSubprocessLauncher *self,
465                                             const gchar         *path)
466 {
467   if (verify_disposition ("stdout", self->flags & ALL_STDOUT_FLAGS, self->stdout_fd, path))
468     {
469       g_free (self->stdout_path);
470       self->stdout_path = g_strdup (path);
471     }
472 }
473
474 /**
475  * g_subprocess_launcher_take_stdout_fd:
476  * @self: a #GSubprocessLauncher
477  * @fd: a file descriptor, or -1
478  *
479  * Sets the file descriptor to use as the stdout for spawned processes.
480  *
481  * If @fd is -1 then any previously given fd is unset.
482  *
483  * Note that the default behaviour is to pass stdout through to the
484  * stdout of the parent process.
485  *
486  * The passed @fd is noted but will not be touched in the current
487  * process.  It is therefore necessary that it be kept open by the
488  * caller until the subprocess is spawned.  The file descriptor will
489  * also not be explicitly closed on the child side, so it must be marked
490  * O_CLOEXEC if that's what you want.
491  *
492  * You may not set a stdout fd if a stdout file path is already set or
493  * if the launcher flags contain any flags directing stdout elsewhere.
494  *
495  * This feature is only available on UNIX.
496  *
497  * Since: 2.40
498  **/
499 void
500 g_subprocess_launcher_take_stdout_fd (GSubprocessLauncher *self,
501                                       gint                 fd)
502 {
503   if (verify_disposition ("stdout", self->flags & ALL_STDOUT_FLAGS, fd, self->stdout_path))
504     assign_fd (&self->stdout_fd, fd);
505 }
506
507 /**
508  * g_subprocess_launcher_set_stderr_file_path:
509  * @self: a #GSubprocessLauncher
510  * @path: a filename or %NULL
511  *
512  * Sets the file path to use as the stderr for spawned processes.
513  *
514  * If @path is %NULL then any previously given path is unset.
515  *
516  * The file will be created or truncated when the process is spawned, as
517  * would be the case if using '2>' at the shell.
518  *
519  * If you want to send both stdout and stderr to the same file then use
520  * %G_SUBPROCESS_FLAGS_STDERR_MERGE.
521  *
522  * You may not set a stderr file path if a stderr fd is already set or
523  * if the launcher flags contain any flags directing stderr elsewhere.
524  *
525  * This feature is only available on UNIX.
526  *
527  * Since: 2.40
528  **/
529 void
530 g_subprocess_launcher_set_stderr_file_path (GSubprocessLauncher *self,
531                                             const gchar         *path)
532 {
533   if (verify_disposition ("stderr", self->flags & ALL_STDERR_FLAGS, self->stderr_fd, path))
534     {
535       g_free (self->stderr_path);
536       self->stderr_path = g_strdup (path);
537     }
538 }
539
540 /**
541  * g_subprocess_launcher_take_stderr_fd:
542  * @self: a #GSubprocessLauncher
543  * @fd: a file descriptor, or -1
544  *
545  * Sets the file descriptor to use as the stderr for spawned processes.
546  *
547  * If @fd is -1 then any previously given fd is unset.
548  *
549  * Note that the default behaviour is to pass stderr through to the
550  * stderr of the parent process.
551  *
552  * The passed @fd belongs to the #GSubprocessLauncher.  It will be
553  * automatically closed when the launcher is finalized.  The file
554  * descriptor will also be closed on the child side when executing the
555  * spawned process.
556  *
557  * You may not set a stderr fd if a stderr file path is already set or
558  * if the launcher flags contain any flags directing stderr elsewhere.
559  *
560  * This feature is only available on UNIX.
561  *
562  * Since: 2.40
563  **/
564 void
565 g_subprocess_launcher_take_stderr_fd (GSubprocessLauncher *self,
566                                      gint                 fd)
567 {
568   if (verify_disposition ("stderr", self->flags & ALL_STDERR_FLAGS, fd, self->stderr_path))
569     assign_fd (&self->stderr_fd, fd);
570 }
571
572 /**
573  * g_subprocess_launcher_pass_fd:
574  * @self: a #GSubprocessLauncher
575  * @source_fd: File descriptor in parent process
576  * @target_fd: Target descriptor for child process
577  *
578  * Pass an arbitrary file descriptor from parent process to
579  * the child.  By default, all file descriptors from the parent
580  * will be closed.  This function allows you to create (for example)
581  * a custom pipe() or socketpair() before launching the process, and
582  * choose the target descriptor in the child.
583  *
584  * An example use case is GNUPG, which has a command line argument
585  * --passphrase-fd providing a file descriptor number where it expects
586  * the passphrase to be written.
587  */
588 void
589 g_subprocess_launcher_pass_fd (GSubprocessLauncher   *self,
590                                gint                   source_fd,
591                                gint                   target_fd)
592 {
593   if (source_fd == target_fd)
594     {
595       g_array_append_val (self->basic_fd_assignments, source_fd);
596     }
597   else
598     {
599       g_array_append_val (self->needdup_fd_assignments, source_fd);
600       g_array_append_val (self->needdup_fd_assignments, target_fd);
601     }
602 }
603
604 /**
605  * g_subprocess_launcher_set_child_setup:
606  * @self: a #GSubprocessLauncher
607  * @child_setup: a #GSpawnChildSetupFunc to use as the child setup function
608  * @user_data: user data for @child_setup
609  * @destroy_notify: a #GDestroyNotify for @user_data
610  *
611  * Sets up a child setup function.
612  *
613  * The child setup function will be called after fork() but before
614  * exec() on the child's side.
615  *
616  * @destroy_notify will not be automatically called on the child's side
617  * of the fork().  It will only be called when the last reference on the
618  * #GSubprocessLauncher is dropped or when a new child setup function is
619  * given.
620  *
621  * %NULL can be given as @child_setup to disable the functionality.
622  *
623  * Child setup functions are only available on UNIX.
624  *
625  * Since: 2.40
626  **/
627 void
628 g_subprocess_launcher_set_child_setup (GSubprocessLauncher  *self,
629                                        GSpawnChildSetupFunc  child_setup,
630                                        gpointer              user_data,
631                                        GDestroyNotify        destroy_notify)
632 {
633   if (self->child_setup_destroy_notify)
634     (* self->child_setup_destroy_notify) (self->child_setup_user_data);
635
636   self->child_setup_func = child_setup;
637   self->child_setup_user_data = user_data;
638   self->child_setup_destroy_notify = destroy_notify;
639 }
640 #endif
641
642 /**
643  * g_subprocess_launcher_spawn:
644  * @self: a #GSubprocessLauncher
645  * @error: Error
646  * @argv0: Command line arguments
647  * @...: Continued arguments, %NULL terminated
648  *
649  * A convenience helper for creating a #GSubprocess given a provided
650  * varargs list of arguments.
651  *
652  * Since: 2.40
653  * Returns: (transfer full): A new #GSubprocess, or %NULL on error (and @error will be set)
654  **/
655 GSubprocess *
656 g_subprocess_launcher_spawn (GSubprocessLauncher  *launcher,
657                              GError              **error,
658                              const gchar          *argv0,
659                              ...)
660 {
661   GSubprocess *result;
662   GPtrArray *args;
663   const gchar *arg;
664   va_list ap;
665
666   g_return_val_if_fail (argv0 != NULL && argv0[0] != '\0', NULL);
667   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
668
669   args = g_ptr_array_new ();
670
671   va_start (ap, argv0);
672   g_ptr_array_add (args, (gchar *) argv0);
673   while ((arg = va_arg (ap, const gchar *)))
674     g_ptr_array_add (args, (gchar *) arg);
675
676   result = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
677
678   g_ptr_array_free (args, TRUE);
679
680   return result;
681
682 }
683
684 /**
685  * g_subprocess_launcher_spawnv:
686  * @self: a #GSubprocessLauncher
687  * @argv: Command line arguments
688  * @error: Error
689  *
690  * A convenience helper for creating a #GSubprocess given a provided
691  * array of arguments.
692  *
693  * Since: 2.40
694  * Returns: (transfer full): A new #GSubprocess, or %NULL on error (and @error will be set)
695  **/
696 GSubprocess *
697 g_subprocess_launcher_spawnv (GSubprocessLauncher  *launcher,
698                               const gchar * const  *argv,
699                               GError              **error)
700 {
701   GSubprocess *subprocess;
702
703   g_return_val_if_fail (argv != NULL && argv[0] != NULL && argv[0][0] != '\0', NULL);
704
705   subprocess = g_object_new (G_TYPE_SUBPROCESS,
706                              "argv", argv,
707                              "flags", launcher->flags,
708                              NULL);
709   g_subprocess_set_launcher (subprocess, launcher);
710
711   if (!g_initable_init (G_INITABLE (subprocess), NULL, error))
712     {
713       g_object_unref (subprocess);
714       return NULL;
715     }
716
717   return subprocess;
718 }