summaryrefslogtreecommitdiffstats
path: root/eglib/gmain.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2007-01-21 14:19:49 +0000
committerJohan Hedberg <johan.hedberg@nokia.com>2007-01-21 14:19:49 +0000
commit7006ed3265196dfeb24ab2790dda6b817462cf48 (patch)
tree712dc8be5646c031fcbc26e3ce99e51c5d8e827a /eglib/gmain.c
parent1c9948d54b407ce9f80a41f8fc3aa2fec2aa3400 (diff)
More g_spawn_async functionality
Diffstat (limited to 'eglib/gmain.c')
-rw-r--r--eglib/gmain.c38
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)