aboutsummaryrefslogtreecommitdiff
path: root/qga/commands-posix.c
diff options
context:
space:
mode:
Diffstat (limited to 'qga/commands-posix.c')
-rw-r--r--qga/commands-posix.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 76c8235272..68da71f232 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -36,8 +36,9 @@
void qmp_guest_shutdown(bool has_mode, const char *mode, Error **err)
{
- int ret;
const char *shutdown_flag;
+ int ret, status;
+ pid_t rpid, pid;
slog("guest-shutdown called, mode: %s", mode);
if (!has_mode || strcmp(mode, "powerdown") == 0) {
@@ -52,8 +53,8 @@ void qmp_guest_shutdown(bool has_mode, const char *mode, Error **err)
return;
}
- ret = fork();
- if (ret == 0) {
+ pid = fork();
+ if (pid == 0) {
/* child, start the shutdown */
setsid();
fclose(stdin);
@@ -66,9 +67,19 @@ void qmp_guest_shutdown(bool has_mode, const char *mode, Error **err)
slog("guest-shutdown failed: %s", strerror(errno));
}
exit(!!ret);
- } else if (ret < 0) {
- error_set(err, QERR_UNDEFINED_ERROR);
+ } else if (pid < 0) {
+ goto exit_err;
}
+
+ do {
+ rpid = waitpid(pid, &status, 0);
+ } while (rpid == -1 && errno == EINTR);
+ if (rpid == pid && WIFEXITED(status) && !WEXITSTATUS(status)) {
+ return;
+ }
+
+exit_err:
+ error_set(err, QERR_UNDEFINED_ERROR);
}
typedef struct GuestFileHandle {