From: Denis V. Lunev Date: Tue, 13 Oct 2015 15:41:21 +0000 (+0300) Subject: qga: handle possible SIGPIPE in guest-file-write X-Git-Tag: v2.5.0-rc0~65^2~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4005b4732e40d3d583510db89ee204b834022d20;p=thirdparty%2Fqemu.git qga: handle possible SIGPIPE in guest-file-write qemu-ga should not exit on guest-file-write to pipe without read end but proper error code should be returned. The behavior of the spawned process should be default thus SIGPIPE processing should be reset to default after fork() but before exec(). Signed-off-by: Denis V. Lunev Signed-off-by: Yuri Pudgorodskiy Reviewed-by: Michael Roth Signed-off-by: Denis V. Lunev Signed-off-by: Michael Roth --- diff --git a/qga/commands.c b/qga/commands.c index ced72d503e7..68e8cfab189 100644 --- a/qga/commands.c +++ b/qga/commands.c @@ -225,6 +225,22 @@ static void guest_exec_child_watch(GPid pid, gint status, gpointer data) g_spawn_close_pid(pid); } +/** Reset ignored signals back to default. */ +static void guest_exec_task_setup(gpointer data) +{ +#if !defined(G_OS_WIN32) + struct sigaction sigact; + + memset(&sigact, 0, sizeof(struct sigaction)); + sigact.sa_handler = SIG_DFL; + + if (sigaction(SIGPIPE, &sigact, NULL) != 0) { + slog("sigaction() failed to reset child process's SIGPIPE: %s", + strerror(errno)); + } +#endif +} + GuestExec *qmp_guest_exec(const char *path, bool has_arg, strList *arg, bool has_env, strList *env, @@ -250,7 +266,7 @@ GuestExec *qmp_guest_exec(const char *path, G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, - NULL, NULL, &pid, NULL, NULL, NULL, &gerr); + guest_exec_task_setup, NULL, &pid, NULL, NULL, NULL, &gerr); if (!ret) { error_setg(err, QERR_QGA_COMMAND_FAILED, gerr->message); g_error_free(gerr); diff --git a/qga/main.c b/qga/main.c index aa6a063446f..068169fcbc0 100644 --- a/qga/main.c +++ b/qga/main.c @@ -161,6 +161,12 @@ static gboolean register_signal_handlers(void) g_error("error configuring signal handler: %s", strerror(errno)); } + sigact.sa_handler = SIG_IGN; + if (sigaction(SIGPIPE, &sigact, NULL) != 0) { + g_error("error configuring SIGPIPE signal handler: %s", + strerror(errno)); + } + return true; }