]> git.proxmox.com Git - mirror_qemu.git/blobdiff - os-posix.c
valgrind/i386: avoid false positives on KVM_SET_CLOCK ioctl
[mirror_qemu.git] / os-posix.c
index cb2a7f7ad71c5a08a9ea204e97835e2c41b4d1e2..ba091f1530bfaf6d3a59b720bdb6412058f17b67 100644 (file)
@@ -47,7 +47,7 @@
 static struct passwd *user_pwd;
 static const char *chroot_dir;
 static int daemonize;
-static int fds[2];
+static int daemon_pipe;
 
 void os_setup_early_signal_handling(void)
 {
@@ -204,45 +204,45 @@ static void change_root(void)
 void os_daemonize(void)
 {
     if (daemonize) {
-       pid_t pid;
-
-       if (pipe(fds) == -1)
-           exit(1);
-
-       pid = fork();
-       if (pid > 0) {
-           uint8_t status;
-           ssize_t len;
-
-           close(fds[1]);
-
-       again:
-            len = read(fds[0], &status, 1);
-            if (len == -1 && (errno == EINTR))
-                goto again;
-
-            if (len != 1)
-                exit(1);
-            else if (status == 1) {
-                fprintf(stderr, "Could not acquire pidfile: %s\n", strerror(errno));
-                exit(1);
-            } else
-                exit(0);
-       } else if (pid < 0)
+        pid_t pid;
+        int fds[2];
+
+        if (pipe(fds) == -1) {
             exit(1);
+        }
+
+        pid = fork();
+        if (pid > 0) {
+            uint8_t status;
+            ssize_t len;
 
-       close(fds[0]);
-       qemu_set_cloexec(fds[1]);
+            close(fds[1]);
 
-       setsid();
+            do {
+                len = read(fds[0], &status, 1);
+            } while (len < 0 && errno == EINTR);
 
-       pid = fork();
-       if (pid > 0)
-           exit(0);
-       else if (pid < 0)
-           exit(1);
+            /* only exit successfully if our child actually wrote
+             * a one-byte zero to our pipe, upon successful init */
+            exit(len == 1 && status == 0 ? 0 : 1);
+
+        } else if (pid < 0) {
+            exit(1);
+        }
 
-       umask(027);
+        close(fds[0]);
+        daemon_pipe = fds[1];
+        qemu_set_cloexec(daemon_pipe);
+
+        setsid();
+
+        pid = fork();
+        if (pid > 0) {
+            exit(0);
+        } else if (pid < 0) {
+            exit(1);
+        }
+        umask(027);
 
         signal(SIGTSTP, SIG_IGN);
         signal(SIGTTOU, SIG_IGN);
@@ -255,47 +255,36 @@ void os_setup_post(void)
     int fd = 0;
 
     if (daemonize) {
-       uint8_t status = 0;
-       ssize_t len;
-
-    again1:
-       len = write(fds[1], &status, 1);
-       if (len == -1 && (errno == EINTR))
-           goto again1;
-
-       if (len != 1)
-           exit(1);
-
         if (chdir("/")) {
             perror("not able to chdir to /");
             exit(1);
         }
-       TFR(fd = qemu_open("/dev/null", O_RDWR));
-       if (fd == -1)
-           exit(1);
+        TFR(fd = qemu_open("/dev/null", O_RDWR));
+        if (fd == -1) {
+            exit(1);
+        }
     }
 
     change_root();
     change_process_uid();
 
     if (daemonize) {
+        uint8_t status = 0;
+        ssize_t len;
+
         dup2(fd, 0);
         dup2(fd, 1);
         dup2(fd, 2);
 
         close(fd);
-    }
-}
 
-void os_pidfile_error(void)
-{
-    if (daemonize) {
-        uint8_t status = 1;
-        if (write(fds[1], &status, 1) != 1) {
-            perror("daemonize. Writing to pipe\n");
+        do {        
+            len = write(daemon_pipe, &status, 1);
+        } while (len < 0 && errno == EINTR);
+        if (len != 1) {
+            exit(1);
         }
-    } else
-        fprintf(stderr, "Could not acquire pid file: %s\n", strerror(errno));
+    }
 }
 
 void os_set_line_buffering(void)