+ /* Put the client in a new session so it won't catch signals
+ * intended for the parent. Sharing a session can be
+ * confusing when launching weston under gdb, as the ctrl-c
+ * intended for gdb will pass to the child, and weston
+ * will cleanly shut down when the child exits.
+ */
+ setsid();
+
+ /* do not give our signal mask to the new process */
+ sigfillset(&allsigs);
+ sigprocmask(SIG_UNBLOCK, &allsigs, NULL);
+}
+
+static struct wet_process *
+client_launch(struct weston_compositor *compositor,
+ struct custom_env *child_env,
+ int *no_cloexec_fds,
+ size_t num_no_cloexec_fds,
+ wet_process_cleanup_func_t cleanup,
+ void *cleanup_data)
+{
+ struct ivi_compositor *ivi = to_ivi_compositor(compositor);
+ struct wet_process *proc = NULL;
+ const char *fail_cloexec = "Couldn't unset CLOEXEC on child FDs";
+ const char *fail_seteuid = "Couldn't call seteuid";
+ char *fail_exec;
+ char * const *argp;
+ char * const *envp;
+ pid_t pid;
+ int err;
+ size_t i;
+ size_t written __attribute__((unused));
+
+ argp = custom_env_get_argp(child_env);
+ envp = custom_env_get_envp(child_env);
+
+ weston_log("launching '%s'\n", argp[0]);
+ str_printf(&fail_exec, "Error: Couldn't launch client '%s'\n", argp[0]);
+
+ pid = fork();
+ switch (pid) {
+ case 0:
+ cleanup_for_child_process();
+
+ /* Launch clients as the user. Do not launch clients with wrong euid. */
+ if (seteuid(getuid()) == -1) {
+ written = write(STDERR_FILENO, fail_seteuid,
+ strlen(fail_seteuid));
+ _exit(EXIT_FAILURE);
+ }
+
+ for (i = 0; i < num_no_cloexec_fds; i++) {
+ err = os_fd_clear_cloexec(no_cloexec_fds[i]);
+ if (err < 0) {
+ written = write(STDERR_FILENO, fail_cloexec,
+ strlen(fail_cloexec));
+ _exit(EXIT_FAILURE);
+ }
+ }
+
+ execve(argp[0], argp, envp);
+
+ if (fail_exec)
+ written = write(STDERR_FILENO, fail_exec,
+ strlen(fail_exec));
+ _exit(EXIT_FAILURE);
+
+ default:
+ proc = xzalloc(sizeof(*proc));
+ proc->pid = pid;
+ proc->cleanup = cleanup;
+ proc->cleanup_data = cleanup_data;
+ proc->path = strdup(argp[0]);
+ wl_list_insert(&ivi->child_process_list, &proc->link);
+ break;
+
+ case -1:
+ weston_log("weston_client_launch: "
+ "fork failed while launching '%s': %s\n", argp[0],
+ strerror(errno));
+ break;
+ }
+
+ custom_env_fini(child_env);
+ free(fail_exec);
+ return proc;
+}
+
+static struct weston_config *
+ivi_get_config(struct weston_compositor *ec)
+{
+ struct ivi_compositor *ivi = to_ivi_compositor(ec);
+
+ return ivi->config;
+}
+
+
+static struct wl_client *