aboutsummaryrefslogtreecommitdiff
path: root/qga/commands.c
diff options
context:
space:
mode:
authorDenis V. Lunev <den@openvz.org>2015-10-13 18:41:21 +0300
committerMichael Roth <mdroth@linux.vnet.ibm.com>2015-10-19 18:31:54 -0500
commit4005b4732e40d3d583510db89ee204b834022d20 (patch)
tree65ae3ded96b16a1afb4390c94d23a8815900d540 /qga/commands.c
parentd697e30cfff29a6a72e3197a218294ba52e7f0c6 (diff)
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 <den@openvz.org> Signed-off-by: Yuri Pudgorodskiy <yur@virtuozzo.com> Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com> Signed-off-by: Denis V. Lunev <den@openvz.org> Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Diffstat (limited to 'qga/commands.c')
-rw-r--r--qga/commands.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/qga/commands.c b/qga/commands.c
index ced72d503e..68e8cfab18 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);