diff --git a/os-posix.c b/os-posix.c index 6417d16dca..1672e06550 100644 --- a/os-posix.c +++ b/os-posix.c @@ -39,6 +39,8 @@ static struct passwd *user_pwd; static const char *chroot_dir; +static int daemonize; +static int fds[2]; void os_setup_early_signal_handling(void) { @@ -160,6 +162,9 @@ void os_parse_cmd_args(int index, const char *optarg) case QEMU_OPTION_chroot: chroot_dir = optarg; break; + case QEMU_OPTION_daemonize: + daemonize = 1; + break; } return; } @@ -196,3 +201,100 @@ void os_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) + exit(1); + + close(fds[0]); + qemu_set_cloexec(fds[1]); + + setsid(); + + pid = fork(); + if (pid > 0) + exit(0); + else if (pid < 0) + exit(1); + + umask(027); + + signal(SIGTSTP, SIG_IGN); + signal(SIGTTOU, SIG_IGN); + signal(SIGTTIN, SIG_IGN); + } +} + +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); + } + + os_change_root(); + os_change_process_uid(); + + if (daemonize) { + 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"); + } + } else + fprintf(stderr, "Could not acquire pid file: %s\n", strerror(errno)); +} diff --git a/os-win32.c b/os-win32.c index aefc535ed0..d98fd77c12 100644 --- a/os-win32.c +++ b/os-win32.c @@ -214,3 +214,8 @@ void os_parse_cmd_args(int index, const char *optarg) { return; } + +void os_pidfile_error(void) +{ + fprintf(stderr, "Could not acquire pid file: %s\n", strerror(errno)); +} diff --git a/qemu-os-posix.h b/qemu-os-posix.h index 91c7b68fd2..9b07660de7 100644 --- a/qemu-os-posix.h +++ b/qemu-os-posix.h @@ -33,5 +33,7 @@ static inline void os_host_main_loop_wait(int *timeout) void os_setup_signal_handling(void); void os_change_process_uid(void); void os_change_root(void); +void os_daemonize(void); +void os_setup_post(void); #endif diff --git a/qemu-os-win32.h b/qemu-os-win32.h index e2a97d2cb3..c4aa84a5f2 100644 --- a/qemu-os-win32.h +++ b/qemu-os-win32.h @@ -45,5 +45,7 @@ void os_host_main_loop_wait(int *timeout); static inline void os_setup_signal_handling(void) {} static inline void os_change_process_uid(void) {} static inline void os_change_root(void) {} +static inline void os_daemonize(void) {} +static inline void os_setup_post(void) {} #endif diff --git a/sysemu.h b/sysemu.h index 2162b1d2b9..346cccd76d 100644 --- a/sysemu.h +++ b/sysemu.h @@ -83,6 +83,7 @@ void do_info_slirp(Monitor *mon); void os_setup_early_signal_handling(void); char *os_find_datadir(const char *argv0); void os_parse_cmd_args(int index, const char *optarg); +void os_pidfile_error(void); typedef enum DisplayType { diff --git a/vl.c b/vl.c index a536784772..cadd988fd2 100644 --- a/vl.c +++ b/vl.c @@ -216,9 +216,6 @@ int no_shutdown = 0; int cursor_hide = 1; int graphic_rotate = 0; uint8_t irq0override = 1; -#ifndef _WIN32 -int daemonize = 0; -#endif const char *watchdog; const char *option_rom[MAX_OPTION_ROMS]; int nb_option_roms; @@ -2301,15 +2298,9 @@ int main(int argc, char **argv, char **envp) const char *loadvm = NULL; QEMUMachine *machine; const char *cpu_model; -#ifndef _WIN32 - int fds[2]; -#endif int tb_size; const char *pid_file = NULL; const char *incoming = NULL; -#ifndef _WIN32 - int fd = 0; -#endif int show_vnc_port = 0; int defconfig = 1; @@ -2975,11 +2966,6 @@ int main(int argc, char **argv, char **envp) exit(1); } break; -#ifndef _WIN32 - case QEMU_OPTION_daemonize: - daemonize = 1; - break; -#endif case QEMU_OPTION_option_rom: if (nb_option_roms >= MAX_OPTION_ROMS) { fprintf(stderr, "Too many option ROMs\n"); @@ -3194,64 +3180,10 @@ int main(int argc, char **argv, char **envp) } #endif -#ifndef _WIN32 - 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) - exit(1); - - close(fds[0]); - qemu_set_cloexec(fds[1]); - - setsid(); - - pid = fork(); - if (pid > 0) - exit(0); - else if (pid < 0) - exit(1); - - umask(027); - - signal(SIGTSTP, SIG_IGN); - signal(SIGTTOU, SIG_IGN); - signal(SIGTTIN, SIG_IGN); - } -#endif + os_daemonize(); if (pid_file && qemu_create_pidfile(pid_file) != 0) { -#ifndef _WIN32 - if (daemonize) { - uint8_t status = 1; - if (write(fds[1], &status, 1) != 1) { - perror("daemonize. Writing to pipe\n"); - } - } else -#endif - fprintf(stderr, "Could not acquire pid file: %s\n", strerror(errno)); + os_pidfile_error(); exit(1); } @@ -3520,39 +3452,7 @@ int main(int argc, char **argv, char **envp) vm_start(); } -#ifndef _WIN32 - 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); - } - - os_change_root(); - os_change_process_uid(); - - if (daemonize) { - dup2(fd, 0); - dup2(fd, 1); - dup2(fd, 2); - - close(fd); - } -#endif + os_setup_post(); main_loop(); quit_timers();