1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright © 2012 Red Hat, Inc.
4 * Copyright © 2012-2013 Canonical Limited
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * See the included COPYING file for more information.
13 * Authors: Colin Walters <walters@verbum.org>
14 * Ryan Lortie <desrt@desrt.ca>
18 * SECTION:gsubprocesslauncher
19 * @title: GSubprocess Launcher
20 * @short_description: Environment options for launching a child process
23 * This class contains a set of options for launching child processes,
24 * such as where its standard input and output will be directed, the
25 * argument list, the environment, and more.
27 * While the #GSubprocess class has high level functions covering
28 * popular cases, use of this class allows access to more advanced
29 * options. It can also be used to launch multiple subprocesses with
30 * a similar configuration.
35 #define ALL_STDIN_FLAGS (G_SUBPROCESS_FLAGS_STDIN_PIPE | \
36 G_SUBPROCESS_FLAGS_STDIN_INHERIT)
37 #define ALL_STDOUT_FLAGS (G_SUBPROCESS_FLAGS_STDOUT_PIPE | \
38 G_SUBPROCESS_FLAGS_STDOUT_SILENCE)
39 #define ALL_STDERR_FLAGS (G_SUBPROCESS_FLAGS_STDERR_PIPE | \
40 G_SUBPROCESS_FLAGS_STDERR_SILENCE | \
41 G_SUBPROCESS_FLAGS_STDERR_MERGE)
45 #include "gsubprocesslauncher-private.h"
46 #include "gioenumtypes.h"
47 #include "gsubprocess.h"
48 #include "ginitable.h"
55 typedef GObjectClass GSubprocessLauncherClass
;
57 G_DEFINE_TYPE (GSubprocessLauncher
, g_subprocess_launcher
, G_TYPE_OBJECT
)
60 verify_disposition (const gchar
*stream_name
,
61 GSubprocessFlags filtered_flags
,
63 const gchar
*filename
)
69 else if (((filtered_flags
- 1) & filtered_flags
) == 0)
72 n_bits
= 2; /* ...or more */
74 if (n_bits
+ (fd
>= 0) + (filename
!= NULL
) > 1)
78 err
= g_string_new (NULL
);
84 class = g_type_class_peek (G_TYPE_SUBPROCESS_FLAGS
);
86 for (i
= 0; i
< class->n_values
; i
++)
88 const GFlagsValue
*value
= &class->values
[i
];
90 if (filtered_flags
& value
->value
)
91 g_string_append_printf (err
, " %s", value
->value_name
);
94 g_type_class_unref (class);
98 g_string_append_printf (err
, " g_subprocess_launcher_take_%s_fd()", stream_name
);
101 g_string_append_printf (err
, " g_subprocess_launcher_set_%s_file_path()", stream_name
);
103 g_critical ("You may specify at most one disposition for the %s stream, but you specified:%s.",
104 stream_name
, err
->str
);
105 g_string_free (err
, TRUE
);
114 verify_flags (GSubprocessFlags flags
)
116 return verify_disposition ("stdin", flags
& ALL_STDIN_FLAGS
, -1, NULL
) &&
117 verify_disposition ("stdout", flags
& ALL_STDOUT_FLAGS
, -1, NULL
) &&
118 verify_disposition ("stderr", flags
& ALL_STDERR_FLAGS
, -1, NULL
);
122 g_subprocess_launcher_set_property (GObject
*object
, guint prop_id
,
123 const GValue
*value
, GParamSpec
*pspec
)
125 GSubprocessLauncher
*launcher
= G_SUBPROCESS_LAUNCHER (object
);
127 g_assert (prop_id
== 1);
129 if (verify_flags (g_value_get_flags (value
)))
130 launcher
->flags
= g_value_get_flags (value
);
134 g_subprocess_launcher_finalize (GObject
*object
)
136 GSubprocessLauncher
*self
= G_SUBPROCESS_LAUNCHER (object
);
141 g_free (self
->stdin_path
);
142 g_free (self
->stdout_path
);
143 g_free (self
->stderr_path
);
145 if (self
->stdin_fd
!= -1)
146 close (self
->stdin_fd
);
148 if (self
->stdout_fd
!= -1)
149 close (self
->stdout_fd
);
151 if (self
->stderr_fd
!= -1)
152 close (self
->stderr_fd
);
154 if (self
->basic_fd_assignments
)
156 for (i
= 0; i
< self
->basic_fd_assignments
->len
; i
++)
157 (void) close (g_array_index (self
->basic_fd_assignments
, int, i
));
158 g_array_unref (self
->basic_fd_assignments
);
160 if (self
->needdup_fd_assignments
)
162 for (i
= 0; i
< self
->needdup_fd_assignments
->len
; i
+= 2)
163 (void) close (g_array_index (self
->needdup_fd_assignments
, int, i
));
164 g_array_unref (self
->needdup_fd_assignments
);
167 if (self
->child_setup_destroy_notify
)
168 (* self
->child_setup_destroy_notify
) (self
->child_setup_user_data
);
171 g_strfreev (self
->envp
);
174 G_OBJECT_CLASS (g_subprocess_launcher_parent_class
)->finalize (object
);
178 g_subprocess_launcher_init (GSubprocessLauncher
*self
)
180 self
->envp
= g_get_environ ();
184 self
->stdout_fd
= -1;
185 self
->stderr_fd
= -1;
186 self
->basic_fd_assignments
= g_array_new (FALSE
, 0, sizeof (int));
187 self
->needdup_fd_assignments
= g_array_new (FALSE
, 0, sizeof (int));
192 g_subprocess_launcher_class_init (GSubprocessLauncherClass
*class)
194 GObjectClass
*gobject_class
= G_OBJECT_CLASS (class);
196 gobject_class
->set_property
= g_subprocess_launcher_set_property
;
197 gobject_class
->finalize
= g_subprocess_launcher_finalize
;
199 g_object_class_install_property (gobject_class
, 1,
200 g_param_spec_flags ("flags", "Flags", "GSubprocessFlags for launched processes",
201 G_TYPE_SUBPROCESS_FLAGS
, 0, G_PARAM_WRITABLE
|
202 G_PARAM_STATIC_STRINGS
| G_PARAM_CONSTRUCT_ONLY
));
206 * g_subprocess_launcher_new:
207 * @flags: #GSubprocessFlags
209 * Creates a new #GSubprocessLauncher.
211 * The launcher is created with the default options. A copy of the
212 * environment of the calling process is made at the time of this call
213 * and will be used as the environment that the process is launched in.
217 GSubprocessLauncher
*
218 g_subprocess_launcher_new (GSubprocessFlags flags
)
220 if (!verify_flags (flags
))
223 return g_object_new (G_TYPE_SUBPROCESS_LAUNCHER
,
229 * g_subprocess_launcher_set_environ:
230 * @self: a #GSubprocess
231 * @env: (array zero-terminated=1): the replacement environment
233 * Replace the entire environment of processes launched from this
234 * launcher with the given 'environ' variable.
236 * Typically you will build this variable by using g_listenv() to copy
237 * the process 'environ' and using the functions g_environ_setenv(),
238 * g_environ_unsetenv(), etc.
240 * As an alternative, you can use g_subprocess_launcher_setenv(),
241 * g_subprocess_launcher_unsetenv(), etc.
243 * Pass an empty array to set an empty environment. Pass %NULL to inherit the
244 * parent process’ environment. As of GLib 2.54, the parent process’ environment
245 * will be copied when g_subprocess_launcher_set_environ() is called.
246 * Previously, it was copied when the subprocess was executed. This means the
247 * copied environment may now be modified (using g_subprocess_launcher_setenv(),
248 * etc.) before launching the subprocess.
250 * On UNIX, all strings in this array can be arbitrary byte strings.
251 * On Windows, they should be in UTF-8.
256 g_subprocess_launcher_set_environ (GSubprocessLauncher
*self
,
259 g_strfreev (self
->envp
);
260 self
->envp
= g_strdupv (env
);
262 if (self
->envp
== NULL
)
263 self
->envp
= g_get_environ ();
267 * g_subprocess_launcher_setenv:
268 * @self: a #GSubprocess
269 * @variable: the environment variable to set, must not contain '='
270 * @value: the new value for the variable
271 * @overwrite: whether to change the variable if it already exists
273 * Sets the environment variable @variable in the environment of
274 * processes launched from this launcher.
276 * On UNIX, both the variable's name and value can be arbitrary byte
277 * strings, except that the variable's name cannot contain '='.
278 * On Windows, they should be in UTF-8.
283 g_subprocess_launcher_setenv (GSubprocessLauncher
*self
,
284 const gchar
*variable
,
288 self
->envp
= g_environ_setenv (self
->envp
, variable
, value
, overwrite
);
292 * g_subprocess_launcher_unsetenv:
293 * @self: a #GSubprocess
294 * @variable: the environment variable to unset, must not contain '='
296 * Removes the environment variable @variable from the environment of
297 * processes launched from this launcher.
299 * On UNIX, the variable's name can be an arbitrary byte string not
300 * containing '='. On Windows, it should be in UTF-8.
305 g_subprocess_launcher_unsetenv (GSubprocessLauncher
*self
,
306 const gchar
*variable
)
308 self
->envp
= g_environ_unsetenv (self
->envp
, variable
);
312 * g_subprocess_launcher_getenv:
313 * @self: a #GSubprocess
314 * @variable: the environment variable to get
316 * Returns the value of the environment variable @variable in the
317 * environment of processes launched from this launcher.
319 * On UNIX, the returned string can be an arbitrary byte string.
320 * On Windows, it will be UTF-8.
322 * Returns: the value of the environment variable, %NULL if unset
327 g_subprocess_launcher_getenv (GSubprocessLauncher
*self
,
328 const gchar
*variable
)
330 return g_environ_getenv (self
->envp
, variable
);
334 * g_subprocess_launcher_set_cwd:
335 * @self: a #GSubprocess
336 * @cwd: (type filename): the cwd for launched processes
338 * Sets the current working directory that processes will be launched
341 * By default processes are launched with the current working directory
342 * of the launching process at the time of launch.
347 g_subprocess_launcher_set_cwd (GSubprocessLauncher
*self
,
351 self
->cwd
= g_strdup (cwd
);
355 * g_subprocess_launcher_set_flags:
356 * @self: a #GSubprocessLauncher
357 * @flags: #GSubprocessFlags
359 * Sets the flags on the launcher.
361 * The default flags are %G_SUBPROCESS_FLAGS_NONE.
363 * You may not set flags that specify conflicting options for how to
364 * handle a particular stdio stream (eg: specifying both
365 * %G_SUBPROCESS_FLAGS_STDIN_PIPE and
366 * %G_SUBPROCESS_FLAGS_STDIN_INHERIT).
368 * You may also not set a flag that conflicts with a previous call to a
369 * function like g_subprocess_launcher_set_stdin_file_path() or
370 * g_subprocess_launcher_take_stdout_fd().
375 g_subprocess_launcher_set_flags (GSubprocessLauncher
*self
,
376 GSubprocessFlags flags
)
378 const gchar
*stdin_path
= NULL
, *stdout_path
= NULL
, *stderr_path
= NULL
;
379 gint stdin_fd
= -1, stdout_fd
= -1, stderr_fd
= -1;
382 stdin_fd
= self
->stdin_fd
;
383 stdout_fd
= self
->stdout_fd
;
384 stderr_fd
= self
->stderr_fd
;
385 stdin_path
= self
->stdin_path
;
386 stdout_path
= self
->stdout_path
;
387 stderr_path
= self
->stderr_path
;
390 if (verify_disposition ("stdin", flags
& ALL_STDIN_FLAGS
, stdin_fd
, stdin_path
) &&
391 verify_disposition ("stdout", flags
& ALL_STDOUT_FLAGS
, stdout_fd
, stdout_path
) &&
392 verify_disposition ("stderr", flags
& ALL_STDERR_FLAGS
, stderr_fd
, stderr_path
))
398 assign_fd (gint
*fd_ptr
, gint fd
)
410 flags
= fcntl (fd
, F_GETFD
);
411 if (~flags
& FD_CLOEXEC
)
412 fcntl (fd
, F_SETFD
, flags
| FD_CLOEXEC
);
417 * g_subprocess_launcher_set_stdin_file_path:
418 * @self: a #GSubprocessLauncher
419 * @path: (type filename) (nullable: a filename or %NULL
421 * Sets the file path to use as the stdin for spawned processes.
423 * If @path is %NULL then any previously given path is unset.
425 * The file must exist or spawning the process will fail.
427 * You may not set a stdin file path if a stdin fd is already set or if
428 * the launcher flags contain any flags directing stdin elsewhere.
430 * This feature is only available on UNIX.
435 g_subprocess_launcher_set_stdin_file_path (GSubprocessLauncher
*self
,
438 if (verify_disposition ("stdin", self
->flags
& ALL_STDIN_FLAGS
, self
->stdin_fd
, path
))
440 g_free (self
->stdin_path
);
441 self
->stdin_path
= g_strdup (path
);
446 * g_subprocess_launcher_take_stdin_fd:
447 * @self: a #GSubprocessLauncher
448 * @fd: a file descriptor, or -1
450 * Sets the file descriptor to use as the stdin for spawned processes.
452 * If @fd is -1 then any previously given fd is unset.
454 * Note that if your intention is to have the stdin of the calling
455 * process inherited by the child then %G_SUBPROCESS_FLAGS_STDIN_INHERIT
456 * is a better way to go about doing that.
458 * The passed @fd is noted but will not be touched in the current
459 * process. It is therefore necessary that it be kept open by the
460 * caller until the subprocess is spawned. The file descriptor will
461 * also not be explicitly closed on the child side, so it must be marked
462 * O_CLOEXEC if that's what you want.
464 * You may not set a stdin fd if a stdin file path is already set or if
465 * the launcher flags contain any flags directing stdin elsewhere.
467 * This feature is only available on UNIX.
472 g_subprocess_launcher_take_stdin_fd (GSubprocessLauncher
*self
,
475 if (verify_disposition ("stdin", self
->flags
& ALL_STDIN_FLAGS
, fd
, self
->stdin_path
))
476 assign_fd (&self
->stdin_fd
, fd
);
480 * g_subprocess_launcher_set_stdout_file_path:
481 * @self: a #GSubprocessLauncher
482 * @path: (type filename) (nullable): a filename or %NULL
484 * Sets the file path to use as the stdout for spawned processes.
486 * If @path is %NULL then any previously given path is unset.
488 * The file will be created or truncated when the process is spawned, as
489 * would be the case if using '>' at the shell.
491 * You may not set a stdout file path if a stdout fd is already set or
492 * if the launcher flags contain any flags directing stdout elsewhere.
494 * This feature is only available on UNIX.
499 g_subprocess_launcher_set_stdout_file_path (GSubprocessLauncher
*self
,
502 if (verify_disposition ("stdout", self
->flags
& ALL_STDOUT_FLAGS
, self
->stdout_fd
, path
))
504 g_free (self
->stdout_path
);
505 self
->stdout_path
= g_strdup (path
);
510 * g_subprocess_launcher_take_stdout_fd:
511 * @self: a #GSubprocessLauncher
512 * @fd: a file descriptor, or -1
514 * Sets the file descriptor to use as the stdout for spawned processes.
516 * If @fd is -1 then any previously given fd is unset.
518 * Note that the default behaviour is to pass stdout through to the
519 * stdout of the parent process.
521 * The passed @fd is noted but will not be touched in the current
522 * process. It is therefore necessary that it be kept open by the
523 * caller until the subprocess is spawned. The file descriptor will
524 * also not be explicitly closed on the child side, so it must be marked
525 * O_CLOEXEC if that's what you want.
527 * You may not set a stdout fd if a stdout file path is already set or
528 * if the launcher flags contain any flags directing stdout elsewhere.
530 * This feature is only available on UNIX.
535 g_subprocess_launcher_take_stdout_fd (GSubprocessLauncher
*self
,
538 if (verify_disposition ("stdout", self
->flags
& ALL_STDOUT_FLAGS
, fd
, self
->stdout_path
))
539 assign_fd (&self
->stdout_fd
, fd
);
543 * g_subprocess_launcher_set_stderr_file_path:
544 * @self: a #GSubprocessLauncher
545 * @path: (type filename) (nullable): a filename or %NULL
547 * Sets the file path to use as the stderr for spawned processes.
549 * If @path is %NULL then any previously given path is unset.
551 * The file will be created or truncated when the process is spawned, as
552 * would be the case if using '2>' at the shell.
554 * If you want to send both stdout and stderr to the same file then use
555 * %G_SUBPROCESS_FLAGS_STDERR_MERGE.
557 * You may not set a stderr file path if a stderr fd is already set or
558 * if the launcher flags contain any flags directing stderr elsewhere.
560 * This feature is only available on UNIX.
565 g_subprocess_launcher_set_stderr_file_path (GSubprocessLauncher
*self
,
568 if (verify_disposition ("stderr", self
->flags
& ALL_STDERR_FLAGS
, self
->stderr_fd
, path
))
570 g_free (self
->stderr_path
);
571 self
->stderr_path
= g_strdup (path
);
576 * g_subprocess_launcher_take_stderr_fd:
577 * @self: a #GSubprocessLauncher
578 * @fd: a file descriptor, or -1
580 * Sets the file descriptor to use as the stderr for spawned processes.
582 * If @fd is -1 then any previously given fd is unset.
584 * Note that the default behaviour is to pass stderr through to the
585 * stderr of the parent process.
587 * The passed @fd belongs to the #GSubprocessLauncher. It will be
588 * automatically closed when the launcher is finalized. The file
589 * descriptor will also be closed on the child side when executing the
592 * You may not set a stderr fd if a stderr file path is already set or
593 * if the launcher flags contain any flags directing stderr elsewhere.
595 * This feature is only available on UNIX.
600 g_subprocess_launcher_take_stderr_fd (GSubprocessLauncher
*self
,
603 if (verify_disposition ("stderr", self
->flags
& ALL_STDERR_FLAGS
, fd
, self
->stderr_path
))
604 assign_fd (&self
->stderr_fd
, fd
);
608 * g_subprocess_launcher_take_fd:
609 * @self: a #GSubprocessLauncher
610 * @source_fd: File descriptor in parent process
611 * @target_fd: Target descriptor for child process
613 * Transfer an arbitrary file descriptor from parent process to the
614 * child. This function takes "ownership" of the fd; it will be closed
615 * in the parent when @self is freed.
617 * By default, all file descriptors from the parent will be closed.
618 * This function allows you to create (for example) a custom pipe() or
619 * socketpair() before launching the process, and choose the target
620 * descriptor in the child.
622 * An example use case is GNUPG, which has a command line argument
623 * --passphrase-fd providing a file descriptor number where it expects
624 * the passphrase to be written.
627 g_subprocess_launcher_take_fd (GSubprocessLauncher
*self
,
631 if (source_fd
== target_fd
)
633 g_array_append_val (self
->basic_fd_assignments
, source_fd
);
637 g_array_append_val (self
->needdup_fd_assignments
, source_fd
);
638 g_array_append_val (self
->needdup_fd_assignments
, target_fd
);
643 * g_subprocess_launcher_set_child_setup:
644 * @self: a #GSubprocessLauncher
645 * @child_setup: a #GSpawnChildSetupFunc to use as the child setup function
646 * @user_data: user data for @child_setup
647 * @destroy_notify: a #GDestroyNotify for @user_data
649 * Sets up a child setup function.
651 * The child setup function will be called after fork() but before
652 * exec() on the child's side.
654 * @destroy_notify will not be automatically called on the child's side
655 * of the fork(). It will only be called when the last reference on the
656 * #GSubprocessLauncher is dropped or when a new child setup function is
659 * %NULL can be given as @child_setup to disable the functionality.
661 * Child setup functions are only available on UNIX.
666 g_subprocess_launcher_set_child_setup (GSubprocessLauncher
*self
,
667 GSpawnChildSetupFunc child_setup
,
669 GDestroyNotify destroy_notify
)
671 if (self
->child_setup_destroy_notify
)
672 (* self
->child_setup_destroy_notify
) (self
->child_setup_user_data
);
674 self
->child_setup_func
= child_setup
;
675 self
->child_setup_user_data
= user_data
;
676 self
->child_setup_destroy_notify
= destroy_notify
;
681 * g_subprocess_launcher_spawn:
682 * @self: a #GSubprocessLauncher
684 * @argv0: Command line arguments
685 * @...: Continued arguments, %NULL terminated
687 * Creates a #GSubprocess given a provided varargs list of arguments.
690 * Returns: (transfer full): A new #GSubprocess, or %NULL on error (and @error will be set)
693 g_subprocess_launcher_spawn (GSubprocessLauncher
*launcher
,
703 g_return_val_if_fail (argv0
!= NULL
&& argv0
[0] != '\0', NULL
);
704 g_return_val_if_fail (error
== NULL
|| *error
== NULL
, NULL
);
706 args
= g_ptr_array_new ();
708 va_start (ap
, argv0
);
709 g_ptr_array_add (args
, (gchar
*) argv0
);
710 while ((arg
= va_arg (ap
, const gchar
*)))
711 g_ptr_array_add (args
, (gchar
*) arg
);
713 g_ptr_array_add (args
, NULL
);
716 result
= g_subprocess_launcher_spawnv (launcher
, (const gchar
* const *) args
->pdata
, error
);
718 g_ptr_array_free (args
, TRUE
);
725 * g_subprocess_launcher_spawnv:
726 * @self: a #GSubprocessLauncher
727 * @argv: (array zero-terminated=1) (element-type utf8): Command line arguments
730 * Creates a #GSubprocess given a provided array of arguments.
733 * Returns: (transfer full): A new #GSubprocess, or %NULL on error (and @error will be set)
736 g_subprocess_launcher_spawnv (GSubprocessLauncher
*launcher
,
737 const gchar
* const *argv
,
740 GSubprocess
*subprocess
;
742 g_return_val_if_fail (argv
!= NULL
&& argv
[0] != NULL
&& argv
[0][0] != '\0', NULL
);
744 subprocess
= g_object_new (G_TYPE_SUBPROCESS
,
746 "flags", launcher
->flags
,
748 g_subprocess_set_launcher (subprocess
, launcher
);
750 if (!g_initable_init (G_INITABLE (subprocess
), NULL
, error
))
752 g_object_unref (subprocess
);