#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
+/*needed for MAP_POPULATE before including qemu-options.h */
+#include <sys/mman.h>
#include <pwd.h>
#include <libgen.h>
#include "net/slirp.h"
#include "qemu-options.h"
+#ifdef CONFIG_LINUX
+#include <sys/prctl.h>
+#include <sys/syscall.h>
+#endif
+
+#ifdef CONFIG_EVENTFD
+#include <sys/eventfd.h>
+#endif
+
static struct passwd *user_pwd;
static const char *chroot_dir;
static int daemonize;
sigaction(SIGPIPE, &act, NULL);
}
-static void termsig_handler(int signal)
-{
- qemu_system_shutdown_request();
-}
-
-static void sigchld_handler(int signal)
+static void termsig_handler(int signal, siginfo_t *info, void *c)
{
- waitpid(-1, NULL, WNOHANG);
+ qemu_system_killed(info->si_signo, info->si_pid);
}
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.
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;
#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
return;
}
-void os_change_process_uid(void)
+static void change_process_uid(void)
{
if (user_pwd) {
if (setgid(user_pwd->pw_gid) < 0) {
}
}
-void os_change_root(void)
+static void change_root(void)
{
if (chroot_dir) {
if (chroot(chroot_dir) < 0) {
exit(1);
}
- os_change_root();
- os_change_process_uid();
+ change_root();
+ change_process_uid();
if (daemonize) {
dup2(fd, 0);
} else
fprintf(stderr, "Could not acquire pid file: %s\n", strerror(errno));
}
+
+void os_set_line_buffering(void)
+{
+ setvbuf(stdout, NULL, _IOLBF, 0);
+}
+
+/*
+ * Creates an eventfd that looks like a pipe and has EFD_CLOEXEC set.
+ */
+int qemu_eventfd(int fds[2])
+{
+#ifdef CONFIG_EVENTFD
+ int ret;
+
+ ret = eventfd(0, 0);
+ if (ret >= 0) {
+ fds[0] = ret;
+ qemu_set_cloexec(ret);
+ if ((fds[1] = dup(ret)) == -1) {
+ close(ret);
+ return -1;
+ }
+ qemu_set_cloexec(fds[1]);
+ return 0;
+ }
+
+ if (errno != ENOSYS) {
+ return -1;
+ }
+#endif
+
+ return qemu_pipe(fds);
+}
+
+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) {
+ return -1;
+ }
+ len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid());
+ if (write(fd, buffer, len) != len) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int qemu_get_thread_id(void)
+{
+#if defined (__linux__)
+ return syscall(SYS_gettid);
+#else
+ return getpid();
+#endif
+}