diff --git a/glib/gspawn.c b/glib/gspawn.c index a4ea758c4..5496b075d 100644 --- a/glib/gspawn.c +++ b/glib/gspawn.c @@ -67,6 +67,10 @@ #include "glibintl.h" #include "glib-unix.h" +#define INHERITS_OR_NULL_STDIN (G_SPAWN_STDIN_FROM_DEV_NULL | G_SPAWN_CHILD_INHERITS_STDIN) +#define INHERITS_OR_NULL_STDOUT (G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_CHILD_INHERITS_STDOUT) +#define INHERITS_OR_NULL_STDERR (G_SPAWN_STDERR_TO_DEV_NULL | G_SPAWN_CHILD_INHERITS_STDERR) + /* posix_spawn() is assumed the fastest way to spawn, but glibc's * implementation was buggy before glibc 2.24, so avoid it on old versions. */ @@ -728,17 +732,23 @@ g_spawn_async_with_pipes (const gchar *working_directory, * @envp. If both %G_SPAWN_SEARCH_PATH and %G_SPAWN_SEARCH_PATH_FROM_ENVP * are used, the value from @envp takes precedence over the environment. * - * %G_SPAWN_STDOUT_TO_DEV_NULL means that the child's standard output - * will be discarded, instead of going to the same location as the parent's - * standard output. If you use this flag, @stdout_pipe_out must be %NULL. - * - * %G_SPAWN_STDERR_TO_DEV_NULL means that the child's standard error - * will be discarded, instead of going to the same location as the parent's - * standard error. If you use this flag, @stderr_pipe_out must be %NULL. - * * %G_SPAWN_CHILD_INHERITS_STDIN means that the child will inherit the parent's * standard input (by default, the child's standard input is attached to - * `/dev/null`). If you use this flag, @stdin_pipe_out must be %NULL. + * `/dev/null`). %G_SPAWN_STDIN_FROM_DEV_NULL explicitly imposes the default + * behavior. Both flags cannot be enabled at the same time and, in both cases, + * the @stdin_pipe_out argument is ignored. + * + * %G_SPAWN_STDOUT_TO_DEV_NULL means that the child's standard output + * will be discarded (by default, it goes to the same location as the parent's + * standard output). %G_SPAWN_CHILD_INHERITS_STDOUT explicitly imposes the + * default behavior. Both flags cannot be enabled at the same time and, in + * both cases, the @stdout_pipe_out argument is ignored. + * + * %G_SPAWN_STDERR_TO_DEV_NULL means that the child's standard error + * will be discarded (by default, it goes to the same location as the parent's + * standard error). %G_SPAWN_CHILD_INHERITS_STDERR explicitly imposes the + * default behavior. Both flags cannot be enabled at the same time and, in + * both cases, the @stderr_pipe_out argument is ignored. * * It is valid to pass the same FD in multiple parameters (e.g. you can pass * a single FD for both @stdout_fd and @stderr_fd, and include it in @@ -862,18 +872,22 @@ g_spawn_async_with_pipes_and_fds (const gchar *working_directory, { g_return_val_if_fail (argv != NULL, FALSE); g_return_val_if_fail (argv[0] != NULL, FALSE); - g_return_val_if_fail (stdout_pipe_out == NULL || - !(flags & G_SPAWN_STDOUT_TO_DEV_NULL), FALSE); - g_return_val_if_fail (stderr_pipe_out == NULL || - !(flags & G_SPAWN_STDERR_TO_DEV_NULL), FALSE); - /* can't inherit stdin if we have an input pipe. */ - g_return_val_if_fail (stdin_pipe_out == NULL || - !(flags & G_SPAWN_CHILD_INHERITS_STDIN), FALSE); + /* can’t both inherit and set pipes to /dev/null */ + g_return_val_if_fail ((flags & INHERITS_OR_NULL_STDIN) != INHERITS_OR_NULL_STDIN, FALSE); + g_return_val_if_fail ((flags & INHERITS_OR_NULL_STDOUT) != INHERITS_OR_NULL_STDOUT, FALSE); + g_return_val_if_fail ((flags & INHERITS_OR_NULL_STDERR) != INHERITS_OR_NULL_STDERR, FALSE); /* can’t use pipes and stdin/stdout/stderr FDs */ g_return_val_if_fail (stdin_pipe_out == NULL || stdin_fd < 0, FALSE); g_return_val_if_fail (stdout_pipe_out == NULL || stdout_fd < 0, FALSE); g_return_val_if_fail (stderr_pipe_out == NULL || stderr_fd < 0, FALSE); + if ((flags & INHERITS_OR_NULL_STDIN) != 0) + stdin_pipe_out = NULL; + if ((flags & INHERITS_OR_NULL_STDOUT) != 0) + stdout_pipe_out = NULL; + if ((flags & INHERITS_OR_NULL_STDERR) != 0) + stderr_pipe_out = NULL; + return fork_exec (!(flags & G_SPAWN_DO_NOT_REAP_CHILD), working_directory, (const gchar * const *) argv, diff --git a/glib/gspawn.h b/glib/gspawn.h index 3cad30765..5f89c4dba 100644 --- a/glib/gspawn.h +++ b/glib/gspawn.h @@ -162,6 +162,12 @@ typedef void (* GSpawnChildSetupFunc) (gpointer user_data); * Since: 2.34 * @G_SPAWN_CLOEXEC_PIPES: create all pipes with the `O_CLOEXEC` flag set. * Since: 2.40 + * @G_SPAWN_CHILD_INHERITS_STDOUT: the child will inherit the parent's standard output. + * Since: 2.74 + * @G_SPAWN_CHILD_INHERITS_STDERR: the child will inherit the parent's standard error. + * Since: 2.74 + * @G_SPAWN_STDIN_FROM_DEV_NULL: the child's standard input is attached to `/dev/null`. + * Since: 2.74 * * Flags passed to g_spawn_sync(), g_spawn_async() and g_spawn_async_with_pipes(). */ @@ -178,7 +184,34 @@ typedef enum G_SPAWN_CHILD_INHERITS_STDIN = 1 << 5, G_SPAWN_FILE_AND_ARGV_ZERO = 1 << 6, G_SPAWN_SEARCH_PATH_FROM_ENVP = 1 << 7, - G_SPAWN_CLOEXEC_PIPES = 1 << 8 + G_SPAWN_CLOEXEC_PIPES = 1 << 8, + + /** + * G_SPAWN_CHILD_INHERITS_STDOUT: + * + * The child will inherit the parent's standard output. + * + * Since: 2.74 + */ + G_SPAWN_CHILD_INHERITS_STDOUT = 1 << 9, + + /** + * G_SPAWN_CHILD_INHERITS_STDERR: + * + * The child will inherit the parent's standard error. + * + * Since: 2.74 + */ + G_SPAWN_CHILD_INHERITS_STDERR = 1 << 10, + + /** + * G_SPAWN_STDIN_FROM_DEV_NULL: + * + * The child's standard input is attached to `/dev/null`. + * + * Since: 2.74 + */ + G_SPAWN_STDIN_FROM_DEV_NULL = 1 << 11 } GSpawnFlags; GLIB_AVAILABLE_IN_ALL