Not setting SA_RESTART causes interruptible system calls to return with EINTR if a signal is received. This makes the process stoppable by ctrl-c even if it is blocked in I/O. --- configure.ac | 2 +- src/sox.c | 25 ++++++++++++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/configure.ac b/configure.ac index 23138a95d3c4..7d9cede95189 100644 --- a/configure.ac +++ b/configure.ac @@ -207,7 +207,7 @@ AC_HEADER_STDC AC_CHECK_HEADERS(fcntl.h unistd.h byteswap.h sys/stat.h sys/time.h sys/timeb.h sys/types.h sys/utsname.h termios.h glob.h fenv.h) dnl Checks for library functions. -AC_CHECK_FUNCS(strcasecmp strdup popen vsnprintf gettimeofday mkstemp fmemopen) +AC_CHECK_FUNCS(strcasecmp strdup popen vsnprintf gettimeofday mkstemp fmemopen sigaction) dnl Check if math library is needed. AC_SEARCH_LIBS([pow], [m]) diff --git a/src/sox.c b/src/sox.c index fcdac94ded00..15f0df67d9b6 100644 --- a/src/sox.c +++ b/src/sox.c @@ -1574,13 +1574,28 @@ static void open_output_file(void) report_file_info(ofile); } +static void setsig(int sig, void (*handler)(int)) +{ +#ifdef HAVE_SIGACTION + struct sigaction sa; + + sa.sa_handler = handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + + sigaction(sig, &sa, NULL); +#else + signal(sig, handler); +#endif +} + static void sigint(int s) { static struct timeval then; if (input_count > 1 && show_progress && s == SIGINT && is_serial(combine_method) && since(&then, 1.0, sox_true)) { - signal(SIGINT, sigint); + setsig(SIGINT, sigint); user_skip = sox_true; } else user_abort = sox_true; @@ -1790,8 +1805,8 @@ static int process(void) } #endif - signal(SIGTERM, sigint); /* Stop gracefully, as soon as we possibly can. */ - signal(SIGINT , sigint); /* Either skip current input or behave as SIGTERM. */ + setsig(SIGTERM, sigint); /* Stop gracefully, as soon as we possibly can. */ + setsig(SIGINT , sigint); /* Either skip current input or behave as SIGTERM. */ if (very_first_effchain) { struct timeval now; double d; @@ -2920,7 +2935,7 @@ int main(int argc, char **argv) if (ofile->signal.length != SOX_UNSPEC) usage("--ignore-length can be given only for an input file"); - signal(SIGINT, SIG_IGN); /* So child pipes aren't killed by track skip */ + setsig(SIGINT, SIG_IGN); /* So child pipes aren't killed by track skip */ for (i = 0; i < input_count; i++) { size_t j = input_count - 1 - i; /* Open in reverse order 'cos of rec (below) */ file_t * f = files[j]; @@ -2967,7 +2982,7 @@ int main(int argc, char **argv) for (i = 0; i < input_count; i++) set_replay_gain(files[i]->ft->oob.comments, files[i]); - signal(SIGINT, SIG_DFL); + setsig(SIGINT, SIG_DFL); /* Loop through the rest of the arguments looking for effects */ add_eff_chain(); -- 2.17.0 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ SoX-devel mailing list SoX-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/sox-devel