static void idle_launch_client(void *data) { struct test_launcher *launcher = data; pid_t pid; sigset_t allsigs; pid = fork(); if (pid == -1) { weston_log("fatal: failed to fork '%s': %m\n", launcher->exe); weston_compositor_exit_with_code(launcher->compositor, EXIT_FAILURE); return; } if (pid == 0) { sigfillset(&allsigs); sigprocmask(SIG_UNBLOCK, &allsigs, NULL); execl(launcher->exe, launcher->exe, NULL); weston_log("compositor: executing '%s' failed: %m\n", launcher->exe); _exit(EXIT_FAILURE); } launcher->process.pid = pid; launcher->process.cleanup = test_client_sigchld; weston_watch_process(&launcher->process); }
static int weston_xserver_handle_event(int listen_fd, uint32_t mask, void *data) { struct weston_xserver *mxs = data; char display[8], s[8]; int sv[2], client_fd; if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) < 0) { weston_log("socketpair failed\n"); return 1; } mxs->process.pid = fork(); switch (mxs->process.pid) { case 0: /* SOCK_CLOEXEC closes both ends, so we need to unset * the flag on the client fd. */ client_fd = dup(sv[1]); if (client_fd < 0) return 1; snprintf(s, sizeof s, "%d", client_fd); setenv("WAYLAND_SOCKET", s, 1); snprintf(display, sizeof display, ":%d", mxs->display); if (execl(XSERVER_PATH, XSERVER_PATH, display, "-wayland", "-rootless", "-retro", "-nolisten", "all", "-terminate", NULL) < 0) weston_log("exec failed: %m\n"); exit(-1); default: weston_log("forked X server, pid %d\n", mxs->process.pid); close(sv[1]); mxs->client = wl_client_create(mxs->wl_display, sv[0]); weston_watch_process(&mxs->process); wl_event_source_remove(mxs->abstract_source); wl_event_source_remove(mxs->unix_source); break; case -1: weston_log( "failed to fork\n"); break; } return 1; }
static int weston_xserver_handle_event(int listen_fd, uint32_t mask, void *data) { struct weston_xserver *wxs = data; char display[8], s[8], abstract_fd[8], unix_fd[8], wm_fd[8]; int sv[2], wm[2], fd; char *xserver = NULL; struct weston_config_section *section; if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) < 0) { weston_log("wl connection socketpair failed\n"); return 1; } if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, wm) < 0) { weston_log("X wm connection socketpair failed\n"); return 1; } wxs->process.pid = fork(); switch (wxs->process.pid) { case 0: /* SOCK_CLOEXEC closes both ends, so we need to unset * the flag on the client fd. */ fd = dup(sv[1]); if (fd < 0) goto fail; snprintf(s, sizeof s, "%d", fd); setenv("WAYLAND_SOCKET", s, 1); snprintf(display, sizeof display, ":%d", wxs->display); fd = dup(wxs->abstract_fd); if (fd < 0) goto fail; snprintf(abstract_fd, sizeof abstract_fd, "%d", fd); fd = dup(wxs->unix_fd); if (fd < 0) goto fail; snprintf(unix_fd, sizeof unix_fd, "%d", fd); fd = dup(wm[1]); if (fd < 0) goto fail; snprintf(wm_fd, sizeof wm_fd, "%d", fd); section = weston_config_get_section(wxs->compositor->config, "xwayland", NULL, NULL); weston_config_section_get_string(section, "path", &xserver, XSERVER_PATH); /* Ignore SIGUSR1 in the child, which will make the X * server send SIGUSR1 to the parent (weston) when * it's done with initialization. During * initialization the X server will round trip and * block on the wayland compositor, so avoid making * blocking requests (like xcb_connect_to_fd) until * it's done with that. */ signal(SIGUSR1, SIG_IGN); if (execl(xserver, xserver, display, "-rootless", "-listen", abstract_fd, "-listen", unix_fd, "-wm", wm_fd, "-terminate", NULL) < 0) weston_log("exec of '%s %s -rootless " "-listen %s -listen %s -wm %s " "-terminate' failed: %m\n", xserver, display, abstract_fd, unix_fd, wm_fd); fail: _exit(EXIT_FAILURE); default: weston_log("forked X server, pid %d\n", wxs->process.pid); close(sv[1]); wxs->client = wl_client_create(wxs->wl_display, sv[0]); close(wm[1]); wxs->wm_fd = wm[0]; weston_watch_process(&wxs->process); wl_event_source_remove(wxs->abstract_source); wl_event_source_remove(wxs->unix_source); break; case -1: weston_log( "failed to fork\n"); break; } return 1; }