diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2007-01-21 14:19:49 +0000 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2007-01-21 14:19:49 +0000 |
commit | 7006ed3265196dfeb24ab2790dda6b817462cf48 (patch) | |
tree | 712dc8be5646c031fcbc26e3ce99e51c5d8e827a /eglib/gmain.c | |
parent | 1c9948d54b407ce9f80a41f8fc3aa2fec2aa3400 (diff) |
More g_spawn_async functionality
Diffstat (limited to 'eglib/gmain.c')
-rw-r--r-- | eglib/gmain.c | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/eglib/gmain.c b/eglib/gmain.c index fc493878..c3c2ec9b 100644 --- a/eglib/gmain.c +++ b/eglib/gmain.c @@ -673,13 +673,32 @@ static void init_child_pipe(void) static void exec_child(const gchar *working_directory, gchar **argv, gchar **envp, - GSpawnFlags flags) + GSpawnFlags flags, + GSpawnChildSetupFunc child_setup, + gpointer user_data) { - if (chdir(working_directory) < 0) - _exit(EXIT_FAILURE); + int null; - if (execv(argv[0], argv) < 0) + if (working_directory && chdir(working_directory) < 0) _exit(EXIT_FAILURE); + + null = open("/dev/null", O_RDWR); + dup2(null, STDIN_FILENO); + dup2(null, STDOUT_FILENO); + dup2(null, STDERR_FILENO); + if (null > 2) + close(null); + + if (child_setup) + child_setup(user_data); + + if (envp) + execve(argv[0], argv, envp); + else + execv(argv[0], argv); + + /* exec failed if we get here */ + _exit(EXIT_FAILURE); } gboolean g_spawn_async(const gchar *working_directory, @@ -692,16 +711,21 @@ gboolean g_spawn_async(const gchar *working_directory, { GPid pid; + if (access(argv[0], X_OK) < 0) + return FALSE; + if (child_watch_pipe[0] < 0) init_child_pipe(); + /* Flush output streams so child doesn't get them */ + fflush(NULL); + switch (pid = fork()) { case -1: return FALSE; case 0: - if (child_setup) - child_setup(user_data); - exec_child(working_directory, argv, envp, flags); + exec_child(working_directory, argv, envp, flags, + child_setup, user_data); break; default: if (child_pid) |