libweston still used those functions internally, so it was not linkable yet by other compositors. --- src/compositor.c | 144 ------------------------------------------------------ src/main.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+), 144 deletions(-)
diff --git a/src/compositor.c b/src/compositor.c index 5e7a758..c949f64 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -255,150 +255,6 @@ weston_output_mode_switch_to_temporary(struct weston_output *output, } static void -child_client_exec(int sockfd, const char *path) -{ - int clientfd; - char s[32]; - sigset_t allsigs; - - /* do not give our signal mask to the new process */ - sigfillset(&allsigs); - sigprocmask(SIG_UNBLOCK, &allsigs, NULL); - - /* Launch clients as the user. Do not lauch clients with wrong euid.*/ - if (seteuid(getuid()) == -1) { - weston_log("compositor: failed seteuid\n"); - return; - } - - /* SOCK_CLOEXEC closes both ends, so we dup the fd to get a - * non-CLOEXEC fd to pass through exec. */ - clientfd = dup(sockfd); - if (clientfd == -1) { - weston_log("compositor: dup failed: %m\n"); - return; - } - - snprintf(s, sizeof s, "%d", clientfd); - setenv("WAYLAND_SOCKET", s, 1); - - if (execl(path, path, NULL) < 0) - weston_log("compositor: executing '%s' failed: %m\n", - path); -} - -WL_EXPORT struct wl_client * -weston_client_launch(struct weston_compositor *compositor, - struct weston_process *proc, - const char *path, - weston_process_cleanup_func_t cleanup) -{ - int sv[2]; - pid_t pid; - struct wl_client *client; - - weston_log("launching '%s'\n", path); - - if (os_socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, sv) < 0) { - weston_log("weston_client_launch: " - "socketpair failed while launching '%s': %m\n", - path); - return NULL; - } - - pid = fork(); - if (pid == -1) { - close(sv[0]); - close(sv[1]); - weston_log("weston_client_launch: " - "fork failed while launching '%s': %m\n", path); - return NULL; - } - - if (pid == 0) { - child_client_exec(sv[1], path); - _exit(-1); - } - - close(sv[1]); - - client = wl_client_create(compositor->wl_display, sv[0]); - if (!client) { - close(sv[0]); - weston_log("weston_client_launch: " - "wl_client_create failed while launching '%s'.\n", - path); - return NULL; - } - - proc->pid = pid; - proc->cleanup = cleanup; - weston_watch_process(proc); - - return client; -} - -struct process_info { - struct weston_process proc; - char *path; -}; - -static void -process_handle_sigchld(struct weston_process *process, int status) -{ - struct process_info *pinfo = - container_of(process, struct process_info, proc); - - /* - * There are no guarantees whether this runs before or after - * the wl_client destructor. - */ - - if (WIFEXITED(status)) { - weston_log("%s exited with status %d\n", pinfo->path, - WEXITSTATUS(status)); - } else if (WIFSIGNALED(status)) { - weston_log("%s died on signal %d\n", pinfo->path, - WTERMSIG(status)); - } else { - weston_log("%s disappeared\n", pinfo->path); - } - - free(pinfo->path); - free(pinfo); -} - -WL_EXPORT struct wl_client * -weston_client_start(struct weston_compositor *compositor, const char *path) -{ - struct process_info *pinfo; - struct wl_client *client; - - pinfo = zalloc(sizeof *pinfo); - if (!pinfo) - return NULL; - - pinfo->path = strdup(path); - if (!pinfo->path) - goto out_free; - - client = weston_client_launch(compositor, &pinfo->proc, path, - process_handle_sigchld); - if (!client) - goto out_str; - - return client; - -out_str: - free(pinfo->path); - -out_free: - free(pinfo); - - return NULL; -} - -static void region_init_infinite(pixman_region32_t *region) { pixman_region32_init_rect(region, INT32_MIN, INT32_MIN, diff --git a/src/main.c b/src/main.c index 3e6a67f..ad20fea 100644 --- a/src/main.c +++ b/src/main.c @@ -36,6 +36,7 @@ #include <sys/stat.h> #include <sys/wait.h> #include <sys/time.h> +#include <sys/socket.h> #ifdef HAVE_LIBUNWIND #define UNW_LOCAL_ONLY @@ -251,6 +252,150 @@ weston_watch_process(struct weston_process *process) } static void +child_client_exec(int sockfd, const char *path) +{ + int clientfd; + char s[32]; + sigset_t allsigs; + + /* do not give our signal mask to the new process */ + sigfillset(&allsigs); + sigprocmask(SIG_UNBLOCK, &allsigs, NULL); + + /* Launch clients as the user. Do not lauch clients with wrong euid.*/ + if (seteuid(getuid()) == -1) { + weston_log("compositor: failed seteuid\n"); + return; + } + + /* SOCK_CLOEXEC closes both ends, so we dup the fd to get a + * non-CLOEXEC fd to pass through exec. */ + clientfd = dup(sockfd); + if (clientfd == -1) { + weston_log("compositor: dup failed: %m\n"); + return; + } + + snprintf(s, sizeof s, "%d", clientfd); + setenv("WAYLAND_SOCKET", s, 1); + + if (execl(path, path, NULL) < 0) + weston_log("compositor: executing '%s' failed: %m\n", + path); +} + +WL_EXPORT struct wl_client * +weston_client_launch(struct weston_compositor *compositor, + struct weston_process *proc, + const char *path, + weston_process_cleanup_func_t cleanup) +{ + int sv[2]; + pid_t pid; + struct wl_client *client; + + weston_log("launching '%s'\n", path); + + if (os_socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, sv) < 0) { + weston_log("weston_client_launch: " + "socketpair failed while launching '%s': %m\n", + path); + return NULL; + } + + pid = fork(); + if (pid == -1) { + close(sv[0]); + close(sv[1]); + weston_log("weston_client_launch: " + "fork failed while launching '%s': %m\n", path); + return NULL; + } + + if (pid == 0) { + child_client_exec(sv[1], path); + _exit(-1); + } + + close(sv[1]); + + client = wl_client_create(compositor->wl_display, sv[0]); + if (!client) { + close(sv[0]); + weston_log("weston_client_launch: " + "wl_client_create failed while launching '%s'.\n", + path); + return NULL; + } + + proc->pid = pid; + proc->cleanup = cleanup; + weston_watch_process(proc); + + return client; +} + +struct process_info { + struct weston_process proc; + char *path; +}; + +static void +process_handle_sigchld(struct weston_process *process, int status) +{ + struct process_info *pinfo = + container_of(process, struct process_info, proc); + + /* + * There are no guarantees whether this runs before or after + * the wl_client destructor. + */ + + if (WIFEXITED(status)) { + weston_log("%s exited with status %d\n", pinfo->path, + WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + weston_log("%s died on signal %d\n", pinfo->path, + WTERMSIG(status)); + } else { + weston_log("%s disappeared\n", pinfo->path); + } + + free(pinfo->path); + free(pinfo); +} + +WL_EXPORT struct wl_client * +weston_client_start(struct weston_compositor *compositor, const char *path) +{ + struct process_info *pinfo; + struct wl_client *client; + + pinfo = zalloc(sizeof *pinfo); + if (!pinfo) + return NULL; + + pinfo->path = strdup(path); + if (!pinfo->path) + goto out_free; + + client = weston_client_launch(compositor, &pinfo->proc, path, + process_handle_sigchld); + if (!client) + goto out_str; + + return client; + +out_str: + free(pinfo->path); + +out_free: + free(pinfo); + + return NULL; +} + +static void log_uname(void) { struct utsname usys; -- 2.4.4 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel