slirp: simplify fork_exec()
Use g_spawn_async_with_fds() to setup the child. GSpawn handles reaping the child, and closing parent file descriptors. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
This commit is contained in:
parent
0aeb4f2c94
commit
2bdb920ece
75
slirp/misc.c
75
slirp/misc.c
@ -129,56 +129,53 @@ err:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fork_exec_child_setup(gpointer data)
|
||||||
|
{
|
||||||
|
setsid();
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fork_exec(struct socket *so, const char *ex)
|
fork_exec(struct socket *so, const char *ex)
|
||||||
{
|
{
|
||||||
char **argv;
|
GError *err = NULL;
|
||||||
int opt, c, sp[2];
|
char **argv;
|
||||||
pid_t pid;
|
int opt, sp[2];
|
||||||
|
|
||||||
DEBUG_CALL("fork_exec");
|
DEBUG_CALL("fork_exec");
|
||||||
DEBUG_ARG("so = %p", so);
|
DEBUG_ARG("so = %p", so);
|
||||||
DEBUG_ARG("ex = %p", ex);
|
DEBUG_ARG("ex = %p", ex);
|
||||||
|
|
||||||
if (slirp_socketpair_with_oob(sp) < 0) {
|
if (slirp_socketpair_with_oob(sp) < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pid = fork();
|
argv = g_strsplit(ex, " ", -1);
|
||||||
switch(pid) {
|
g_spawn_async_with_fds(NULL /* cwd */,
|
||||||
case -1:
|
argv,
|
||||||
error_report("Error: fork failed: %s", strerror(errno));
|
NULL /* env */,
|
||||||
closesocket(sp[0]);
|
G_SPAWN_SEARCH_PATH,
|
||||||
closesocket(sp[1]);
|
fork_exec_child_setup, NULL /* data */,
|
||||||
return 0;
|
NULL /* child_pid */,
|
||||||
|
sp[1], sp[1], sp[1],
|
||||||
|
&err);
|
||||||
|
g_strfreev(argv);
|
||||||
|
|
||||||
case 0:
|
if (err) {
|
||||||
setsid();
|
error_report("%s", err->message);
|
||||||
dup2(sp[1], 0);
|
g_error_free(err);
|
||||||
dup2(sp[1], 1);
|
closesocket(sp[0]);
|
||||||
dup2(sp[1], 2);
|
closesocket(sp[1]);
|
||||||
for (c = getdtablesize() - 1; c >= 3; c--)
|
return 0;
|
||||||
close(c);
|
}
|
||||||
|
|
||||||
argv = g_strsplit(ex, " ", -1);
|
so->s = sp[0];
|
||||||
execvp(argv[0], (char **)argv);
|
closesocket(sp[1]);
|
||||||
|
socket_set_fast_reuse(so->s);
|
||||||
/* Ooops, failed, let's tell the user why */
|
opt = 1;
|
||||||
fprintf(stderr, "Error: execvp of %s failed: %s\n",
|
qemu_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
|
||||||
argv[0], strerror(errno));
|
qemu_set_nonblock(so->s);
|
||||||
close(0); close(1); close(2); /* XXX */
|
return 1;
|
||||||
exit(1);
|
|
||||||
|
|
||||||
default:
|
|
||||||
so->s = sp[0];
|
|
||||||
closesocket(sp[1]);
|
|
||||||
qemu_add_child_watch(pid);
|
|
||||||
socket_set_fast_reuse(so->s);
|
|
||||||
opt = 1;
|
|
||||||
qemu_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
|
|
||||||
qemu_set_nonblock(so->s);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user