From 612d4cad3e8007c4c8a70181a8bc66730ae3a972 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Wed, 25 Feb 2015 11:15:33 +0100 Subject: [PATCH] Improve signal handler. The signal handler of dss has two issues: (a) it does not check the return value of the write(2) call, and (b) it does not restore errno on exit. The second issue might cause problems on systems where write(2) sets errno also on success. Those problems would be very hard to reproduce and debug. So it is probably a good idea to be conservative here. This commit fixes (a) by printing an error message and calling exit(3) if the write to the signal pipe failed or resulted in a short write. As for (b), we now save a copy of errno before the write(2) call, and restore the old value on success. --- sig.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/sig.c b/sig.c index d2d7e3b..99d3dd3 100644 --- a/sig.c +++ b/sig.c @@ -64,12 +64,27 @@ err_out: exit(EXIT_FAILURE); } -/* - * just write one integer to signal pipe - */ +/* Write the signal number to the signal pipe, abort on errors. */ static void generic_signal_handler(int s) { - write(signal_pipe[1], &s, sizeof(int)); + /* + * Signal handlers that make system calls must save a copy of errno on + * entry to the handler and restore it on exit, to prevent the + * possibility of overwriting a errno value that had previously been + * set in the main program. + */ + int save_errno = errno; + ssize_t ret = write(signal_pipe[1], &s, sizeof(int)); + + if (ret == sizeof(int)) { + errno = save_errno; + return; + } + if (ret < 0) + DSS_EMERG_LOG(("%s\n", strerror(errno))); + else + DSS_EMERG_LOG(("short write to signal pipe\n")); + exit(EXIT_FAILURE); } /** -- 2.39.2