static void handle_signal(int sig) { /* Try to not change errno value in the main program. */ const int saved_errno = errno; switch(sig) { case SIGINT: ui_cancellation_request(); break; case SIGCHLD: received_sigchld(); break; case SIGWINCH: received_sigwinch(); break; case SIGCONT: received_sigcont(); break; /* Shutdown nicely */ case SIGHUP: case SIGQUIT: case SIGTERM: shutdown_nicely(sig, strsignal(sig)); break; } errno = saved_errno; }
BOOL WINAPI ctrl_handler(DWORD dwCtrlType) { LOG_FUNC_ENTER; switch(dwCtrlType) { case CTRL_C_EVENT: case CTRL_BREAK_EVENT: ui_cancellation_request(); break; case CTRL_CLOSE_EVENT: shutdown_nicely(dwCtrlType, "Ctrl-C"); break; case CTRL_LOGOFF_EVENT: shutdown_nicely(dwCtrlType, "Logoff"); break; case CTRL_SHUTDOWN_EVENT: shutdown_nicely(dwCtrlType, "Shutdown"); break; } return TRUE; }
void wait_for_data_from(pid_t pid, FILE *f, int fd) { const struct timeval ts_init = { .tv_sec = 0, .tv_usec = 1000 }; struct timeval ts; fd_set read_ready; FD_ZERO(&read_ready); fd = (f != NULL) ? fileno(f) : fd; do { process_cancel_request(pid); ts = ts_init; FD_SET(fd, &read_ready); } while(select(fd + 1, &read_ready, NULL, NULL, &ts) == 0); /* Inform other parts of the application that cancellation took place. */ if(errno == EINTR) { ui_cancellation_request(); } } int set_sigchld(int block) { const int action = block ? SIG_BLOCK : SIG_UNBLOCK; sigset_t sigchld_mask; return sigemptyset(&sigchld_mask) == -1 || sigaddset(&sigchld_mask, SIGCHLD) == -1 || sigprocmask(action, &sigchld_mask, NULL) == -1; } void process_cancel_request(pid_t pid) { if(ui_cancellation_requested()) { if(kill(pid, SIGINT) != 0) { LOG_SERROR_MSG(errno, "Failed to send SIGINT to " PRINTF_PID_T, pid); } } } int get_proc_exit_status(pid_t pid) { do { int status; if(waitpid(pid, &status, 0) == -1) { if(errno != EINTR) { LOG_SERROR_MSG(errno, "waitpid()"); return -1; } } else { return status; } } while(1); } /* if err == 1 then use stderr and close stdin and stdout */ void _gnuc_noreturn run_from_fork(int pipe[2], int err, char *cmd) { char *args[4]; int nullfd; /* Redirect stderr or stdout to write end of pipe. */ if(dup2(pipe[1], err ? STDERR_FILENO : STDOUT_FILENO) == -1) { exit(1); } close(pipe[0]); /* Close read end of pipe. */ close(STDIN_FILENO); close(err ? STDOUT_FILENO : STDERR_FILENO); /* Send stdout, stdin to /dev/null */ if((nullfd = open("/dev/null", O_RDONLY)) != -1) { if(dup2(nullfd, STDIN_FILENO) == -1) exit(1); if(dup2(nullfd, err ? STDOUT_FILENO : STDERR_FILENO) == -1) exit(1); } args[0] = cfg.shell; args[1] = "-c"; args[2] = cmd; args[3] = NULL; execvp(args[0], args); exit(1); }