diff --git a/src/lib/ecore/ecore_exe_posix.c b/src/lib/ecore/ecore_exe_posix.c index 85b7adee45..635fc0678b 100644 --- a/src/lib/ecore/ecore_exe_posix.c +++ b/src/lib/ecore/ecore_exe_posix.c @@ -289,56 +289,64 @@ _impl_ecore_exe_efl_object_finalize(Eo *obj, Ecore_Exe_Data *exe) pid_t pid = 0; volatile int vfork_exec_errno = 0; + sigset_t newset, oldset; + + sigemptyset(&newset); + sigaddset(&newset, SIGPIPE); + sigaddset(&newset, SIGALRM); + sigaddset(&newset, SIGCHLD); + sigaddset(&newset, SIGUSR1); + sigaddset(&newset, SIGUSR2); + sigaddset(&newset, SIGHUP); + sigaddset(&newset, SIGQUIT); + sigaddset(&newset, SIGINT); + sigaddset(&newset, SIGTERM); + sigaddset(&newset, SIGBUS); + sigaddset(&newset, SIGCONT); + sigaddset(&newset, SIGWINCH); +#ifdef SIGEMT + sigaddset(&newset, SIGEMT); +#endif +#ifdef SIGIO + sigaddset(&newset, SIGIO); +#endif +#ifdef SIGTSTP + sigaddset(&newset, SIGTSTP); +#endif +#ifdef SIGTTIN + sigaddset(&newset, SIGTTIN); +#endif +#ifdef SIGTTOU + sigaddset(&newset, SIGTTOU); +#endif +#ifdef SIGVTALRM + sigaddset(&newset, SIGVTALRM); +#endif +#ifdef SIGPWR + sigaddset(&newset, SIGPWR); +#endif + // block all those nasty signals we don't want messing with things + // in signal handlers while we go from fork to exec in the child + pthread_sigmask(SIG_BLOCK, &newset, &oldset); /* FIXME: I should double check this. After a quick look around, this is already done, but via a more modern method. */ /* signal(SIGPIPE, SIG_IGN); We only want EPIPE on errors */ pid = fork(); if (pid == -1) { + pthread_sigmask(SIG_SETMASK, &oldset, NULL); ERR("Failed to fork process"); pid = 0; } else if (pid == 0) /* child */ { - sigset_t newset; + struct sigaction sa; + int sig; - sigemptyset(&newset); - sigaddset(&newset, SIGPIPE); - sigaddset(&newset, SIGALRM); - sigaddset(&newset, SIGCHLD); - sigaddset(&newset, SIGUSR1); - sigaddset(&newset, SIGUSR2); - sigaddset(&newset, SIGHUP); - sigaddset(&newset, SIGQUIT); - sigaddset(&newset, SIGINT); - sigaddset(&newset, SIGTERM); - sigaddset(&newset, SIGBUS); - sigaddset(&newset, SIGCONT); - sigaddset(&newset, SIGWINCH); -#ifdef SIGEMT - sigaddset(&newset, SIGEMT); -#endif -#ifdef SIGIO - sigaddset(&newset, SIGIO); -#endif -#ifdef SIGTSTP - sigaddset(&newset, SIGTSTP); -#endif -#ifdef SIGTTIN - sigaddset(&newset, SIGTTIN); -#endif -#ifdef SIGTTOU - sigaddset(&newset, SIGTTOU); -#endif -#ifdef SIGVTALRM - sigaddset(&newset, SIGVTALRM); -#endif -#ifdef SIGPWR - sigaddset(&newset, SIGPWR); -#endif - // block all those nasty signals we don't want messing with things - // in signal handlers while we go from fork to exec in the child - pthread_sigmask(SIG_BLOCK, &newset, NULL); + sa.sa_handler = SIG_DFL; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + for (sig = 0; sig < 32; sig++) sigaction(sig, &sa, NULL); #ifdef HAVE_SYSTEMD char **env = NULL, **e; @@ -439,13 +447,15 @@ _impl_ecore_exe_efl_object_finalize(Eo *obj, Ecore_Exe_Data *exe) except[0] = statusPipe[1]; eina_file_close_from(3, except); /* Run the actual command. */ - _ecore_exe_exec_it(exe_cmd, flags); /* no return */ + pthread_sigmask(SIG_SETMASK, &oldset, NULL); + _ecore_exe_exec_it(exe_cmd, flags); /* no return */ } } _exit(-1); } else /* parent */ { + pthread_sigmask(SIG_SETMASK, &oldset, NULL); /* Close the unused pipes. */ E_NO_ERRNO(result, close(statusPipe[1]), ok); diff --git a/src/lib/ecore/efl_exe.c b/src/lib/ecore/efl_exe.c index 445a3dfab2..03c52ab845 100644 --- a/src/lib/ecore/efl_exe.c +++ b/src/lib/ecore/efl_exe.c @@ -435,39 +435,7 @@ _efl_exe_efl_task_run(Eo *obj, Efl_Exe_Data *pd) if (loop) tdl = efl_data_scope_get(loop, EFL_TASK_CLASS); if (pd->env) itr = efl_core_env_content_get(pd->env); if (pd->env) itr2 = efl_core_env_content_get(pd->env); - pd->pid = fork(); - - if (pd->pid != 0) - { - if (itr) eina_iterator_free(itr); - if (itr2) eina_iterator_free(itr2); - // parent process is here inside this if block - if (td->flags & EFL_TASK_FLAGS_USE_STDIN) close(pipe_stdin[0]); - if (td->flags & EFL_TASK_FLAGS_USE_STDOUT) close(pipe_stdout[1]); - // fork failed... close up and clean and release locks - if (pd->pid == -1) - { - _close_fds(pd); - _ecore_signal_pid_unlock(); - return EINA_FALSE; - } - // register this pid in the core sigchild/pid exit code watcher - _ecore_signal_pid_register(pd->pid, pd->fd.exited_write); - pd->exit_handler = - efl_add(EFL_LOOP_HANDLER_CLASS, obj, - efl_loop_handler_fd_set(efl_added, pd->fd.exited_read), - efl_event_callback_add(efl_added, - EFL_LOOP_HANDLER_EVENT_READ, - _cb_exe_exit_read, obj), - efl_loop_handler_active_set(efl_added, - EFL_LOOP_HANDLER_FLAGS_READ)); - _ecore_signal_pid_unlock(); - pd->run = EINA_TRUE; - return EINA_TRUE; - } - // this code is in the child here, and is temporary setup until we - // exec() the child to replace everything. - sigset_t newset; + sigset_t newset, oldset; sigemptyset(&newset); sigaddset(&newset, SIGPIPE); @@ -505,7 +473,47 @@ _efl_exe_efl_task_run(Eo *obj, Efl_Exe_Data *pd) # endif // block all those nasty signals we don't want messing with things // in signal handlers while we go from fork to exec in the child - pthread_sigmask(SIG_BLOCK, &newset, NULL); + pthread_sigmask(SIG_BLOCK, &newset, &oldset); + pd->pid = fork(); + + if (pd->pid != 0) + { + pthread_sigmask(SIG_SETMASK, &oldset, NULL); + if (itr) eina_iterator_free(itr); + if (itr2) eina_iterator_free(itr2); + // parent process is here inside this if block + if (td->flags & EFL_TASK_FLAGS_USE_STDIN) close(pipe_stdin[0]); + if (td->flags & EFL_TASK_FLAGS_USE_STDOUT) close(pipe_stdout[1]); + // fork failed... close up and clean and release locks + if (pd->pid == -1) + { + _close_fds(pd); + _ecore_signal_pid_unlock(); + return EINA_FALSE; + } + // register this pid in the core sigchild/pid exit code watcher + _ecore_signal_pid_register(pd->pid, pd->fd.exited_write); + pd->exit_handler = + efl_add(EFL_LOOP_HANDLER_CLASS, obj, + efl_loop_handler_fd_set(efl_added, pd->fd.exited_read), + efl_event_callback_add(efl_added, + EFL_LOOP_HANDLER_EVENT_READ, + _cb_exe_exit_read, obj), + efl_loop_handler_active_set(efl_added, + EFL_LOOP_HANDLER_FLAGS_READ)); + _ecore_signal_pid_unlock(); + pd->run = EINA_TRUE; + return EINA_TRUE; + } + struct sigaction sa; + int sig; + + sa.sa_handler = SIG_DFL; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + for (sig = 0; sig < 32; sig++) sigaction(sig, &sa, NULL); + // this code is in the child here, and is temporary setup until we + // exec() the child to replace everything. if (td->flags & EFL_TASK_FLAGS_USE_STDIN) close(pipe_stdin[1]); if (td->flags & EFL_TASK_FLAGS_USE_STDOUT) close(pipe_stdout[0]); @@ -633,6 +641,7 @@ _efl_exe_efl_task_run(Eo *obj, Efl_Exe_Data *pd) procctl(P_PID, 0, PROC_PDEATHSIG_CTL, &sig); } # endif + pthread_sigmask(SIG_SETMASK, &oldset, NULL); // actually execute! _exec(cmd, pd->flags, td->flags); // we couldn't exec... uh oh. HAAAAAAAALP!