forked from enlightenment/efl
ecore exe - fig signal block to unblock again - some sys dont on exec
it seems some libc's or systes dont reset signal mask blocks on exec(). this unblocks manuaklly jus befor eexec, moves blocking to before fork and adds a "nuke all signal handlers" in the child process. fixes T8797
This commit is contained in:
parent
b954640db8
commit
07138e1e1d
|
@ -289,18 +289,7 @@ _impl_ecore_exe_efl_object_finalize(Eo *obj, Ecore_Exe_Data *exe)
|
|||
pid_t pid = 0;
|
||||
volatile int vfork_exec_errno = 0;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
ERR("Failed to fork process");
|
||||
pid = 0;
|
||||
}
|
||||
else if (pid == 0) /* child */
|
||||
{
|
||||
sigset_t newset;
|
||||
sigset_t newset, oldset;
|
||||
|
||||
sigemptyset(&newset);
|
||||
sigaddset(&newset, SIGPIPE);
|
||||
|
@ -338,7 +327,26 @@ _impl_ecore_exe_efl_object_finalize(Eo *obj, Ecore_Exe_Data *exe)
|
|||
#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);
|
||||
/* 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 */
|
||||
{
|
||||
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);
|
||||
#ifdef HAVE_SYSTEMD
|
||||
char **env = NULL, **e;
|
||||
|
||||
|
@ -439,6 +447,7 @@ _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. */
|
||||
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
||||
_ecore_exe_exec_it(exe_cmd, flags); /* no return */
|
||||
}
|
||||
}
|
||||
|
@ -446,6 +455,7 @@ _impl_ecore_exe_efl_object_finalize(Eo *obj, Ecore_Exe_Data *exe)
|
|||
}
|
||||
else /* parent */
|
||||
{
|
||||
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
||||
/* Close the unused pipes. */
|
||||
E_NO_ERRNO(result, close(statusPipe[1]), ok);
|
||||
|
||||
|
|
|
@ -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!
|
||||
|
|
Loading…
Reference in New Issue