X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=os-posix.c;h=5c437ca12ca1b66cb515cbebd770a201ae2e91ed;hb=9e07bdf816b186632cda9651ac29bba76d299c03;hp=1672e0655038bcff69d8274762ef015b15e0cd18;hpb=eb505be11b18b09c621dfb19a4e3b5f703c69eeb;p=mirror_qemu.git diff --git a/os-posix.c b/os-posix.c index 1672e06550..5c437ca12c 100644 --- a/os-posix.c +++ b/os-posix.c @@ -28,7 +28,10 @@ #include #include #include +/*needed for MAP_POPULATE before including qemu-options.h */ +#include #include +#include #include /* Needed early for CONFIG_BSD etc. */ @@ -37,6 +40,10 @@ #include "net/slirp.h" #include "qemu-options.h" +#ifdef CONFIG_LINUX +#include +#endif + static struct passwd *user_pwd; static const char *chroot_dir; static int daemonize; @@ -51,14 +58,9 @@ void os_setup_early_signal_handling(void) sigaction(SIGPIPE, &act, NULL); } -static void termsig_handler(int signal) +static void termsig_handler(int signal, siginfo_t *info, void *c) { - qemu_system_shutdown_request(); -} - -static void sigchld_handler(int signal) -{ - waitpid(-1, NULL, WNOHANG); + qemu_system_killed(info->si_signo, info->si_pid); } void os_setup_signal_handling(void) @@ -66,14 +68,11 @@ void os_setup_signal_handling(void) struct sigaction act; memset(&act, 0, sizeof(act)); - act.sa_handler = termsig_handler; + act.sa_sigaction = termsig_handler; + act.sa_flags = SA_SIGINFO; sigaction(SIGINT, &act, NULL); sigaction(SIGHUP, &act, NULL); sigaction(SIGTERM, &act, NULL); - - act.sa_handler = sigchld_handler; - act.sa_flags = SA_NOCLDSTOP; - sigaction(SIGCHLD, &act, NULL); } /* Find a likely location for support files using the location of the binary. @@ -104,7 +103,7 @@ char *os_find_datadir(const char *argv0) size_t len = sizeof(buf) - 1; *buf = '\0'; - if (!sysctl(mib, sizeof(mib)/sizeof(*mib), buf, &len, NULL, 0) && + if (!sysctl(mib, ARRAY_SIZE(mib), buf, &len, NULL, 0) && *buf) { buf[sizeof(buf) - 1] = '\0'; p = buf; @@ -124,12 +123,12 @@ char *os_find_datadir(const char *argv0) max_len = strlen(dir) + MAX(strlen(SHARE_SUFFIX), strlen(BUILD_SUFFIX)) + 1; - res = qemu_mallocz(max_len); + res = g_malloc0(max_len); snprintf(res, max_len, "%s%s", dir, SHARE_SUFFIX); if (access(res, R_OK)) { snprintf(res, max_len, "%s%s", dir, BUILD_SUFFIX); if (access(res, R_OK)) { - qemu_free(res); + g_free(res); res = NULL; } } @@ -139,6 +138,26 @@ char *os_find_datadir(const char *argv0) #undef SHARE_SUFFIX #undef BUILD_SUFFIX +void os_set_proc_name(const char *s) +{ +#if defined(PR_SET_NAME) + char name[16]; + if (!s) + return; + name[sizeof(name) - 1] = 0; + strncpy(name, s, sizeof(name)); + /* Could rewrite argv[0] too, but that's a bit more complicated. + This simple way is enough for `top'. */ + if (prctl(PR_SET_NAME, name)) { + perror("unable to change process name"); + exit(1); + } +#else + fprintf(stderr, "Change of process name not supported by your OS\n"); + exit(1); +#endif +} + /* * Parse OS specific command line options. * return 0 if option handled, -1 otherwise @@ -169,13 +188,18 @@ void os_parse_cmd_args(int index, const char *optarg) return; } -void os_change_process_uid(void) +static void change_process_uid(void) { if (user_pwd) { if (setgid(user_pwd->pw_gid) < 0) { fprintf(stderr, "Failed to setgid(%d)\n", user_pwd->pw_gid); exit(1); } + if (initgroups(user_pwd->pw_name, user_pwd->pw_gid) < 0) { + fprintf(stderr, "Failed to initgroups(\"%s\", %d)\n", + user_pwd->pw_name, user_pwd->pw_gid); + exit(1); + } if (setuid(user_pwd->pw_uid) < 0) { fprintf(stderr, "Failed to setuid(%d)\n", user_pwd->pw_uid); exit(1); @@ -187,7 +211,7 @@ void os_change_process_uid(void) } } -void os_change_root(void) +static void change_root(void) { if (chroot_dir) { if (chroot(chroot_dir) < 0) { @@ -276,8 +300,8 @@ void os_setup_post(void) exit(1); } - os_change_root(); - os_change_process_uid(); + change_root(); + change_process_uid(); if (daemonize) { dup2(fd, 0); @@ -298,3 +322,32 @@ void os_pidfile_error(void) } else fprintf(stderr, "Could not acquire pid file: %s\n", strerror(errno)); } + +void os_set_line_buffering(void) +{ + setvbuf(stdout, NULL, _IOLBF, 0); +} + +int qemu_create_pidfile(const char *filename) +{ + char buffer[128]; + int len; + int fd; + + fd = qemu_open(filename, O_RDWR | O_CREAT, 0600); + if (fd == -1) { + return -1; + } + if (lockf(fd, F_TLOCK, 0) == -1) { + close(fd); + return -1; + } + len = snprintf(buffer, sizeof(buffer), FMT_pid "\n", getpid()); + if (write(fd, buffer, len) != len) { + close(fd); + return -1; + } + + close(fd); + return 0; +}