From 33051a296c4890270d75c6ed22dc074b2ab9520a Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 10 Jun 2024 14:36:28 -0700 Subject: [PATCH] signals: require and always use sigaction() tftpd already requires sigaction() to compile, so there is no reason to use anything else. It also allows for nicer combination of flags. Signed-off-by: H. Peter Anvin --- common/signal.c | 39 ++++++++------------------------------- config.h | 5 +---- configure.ac | 11 ++++++----- tftp/main.c | 4 ++-- tftp/tftp.c | 4 ++-- tftpd/misc.c | 14 +++----------- 6 files changed, 22 insertions(+), 55 deletions(-) diff --git a/common/signal.c b/common/signal.c index 9119d57..ccd4af8 100644 --- a/common/signal.c +++ b/common/signal.c @@ -1,42 +1,19 @@ /* * signal.c * - * Use sigaction() to simulate BSD signal() + * User-friendly wrapper around sigaction(). */ #include "config.h" -#ifdef HAVE_SIGACTION - -sighandler_t tftp_signal(int signum, sighandler_t handler) +int tftp_signal(int signum, sighandler_t handler, int flags) { - struct sigaction action, oldaction; + struct sigaction sa; - memset(&action, 0, sizeof action); - action.sa_handler = handler; - sigemptyset(&action.sa_mask); - sigaddset(&action.sa_mask, signum); - action.sa_flags = SA_RESTART; + memset(&sa, 0, sizeof sa); + sa.sa_handler = handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = flags; - if (sigaction(signum, &action, &oldaction)) - return SIG_ERR; - - return oldaction.sa_handler; + return sigaction(signum, &sa, NULL); } - -#elif defined(HAVE_BSD_SIGNAL) - -sighandler_t tftp_signal(int signum, sighandler_t handler) -{ - return bsd_signal(signum, handler); -} - -#else - -/* This is dangerous at best. Let's hope it works. */ -sighandler_t tftp_signal(int signum, sighandler_t handler) -{ - return signal(signum, handler); -} - -#endif diff --git a/config.h b/config.h index a6a402b..1983058 100644 --- a/config.h +++ b/config.h @@ -282,10 +282,7 @@ char *xstrdup(const char *); #ifndef HAVE_SIGHANDLER_T typedef void (*sighandler_t)(int); #endif -#ifndef SIG_ERR -#define SIG_ERR NULL -#endif -sighandler_t tftp_signal(int, sighandler_t); +int tftp_signal(int, sighandler_t, int); #ifndef HAVE_DUP2 int dup2(int, int); diff --git a/configure.ac b/configure.ac index 8770431..2d4b93d 100644 --- a/configure.ac +++ b/configure.ac @@ -74,9 +74,12 @@ dnl but POSIX requires for socklen_t to be defined. dnl AC_CHECK_TYPES(socklen_t,,, [AC_INCLUDES_DEFAULT -#if HAVE_SYS_TYPES_H +#ifdef HAVE_SYS_TYPES_H # include #endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif ]) AC_SEARCH_LIBS(socket, [socket ws2_32 wsock32], , [AC_MSG_ERROR(socket library not found)]) @@ -85,14 +88,12 @@ AC_CHECK_FUNCS(fcntl) AC_CHECK_FUNCS(setsid) AC_CHECK_FUNCS(recvmsg) AC_CHECK_FUNCS(ftruncate) -AC_CHECK_FUNCS(setreuid) AC_CHECK_FUNCS(setresuid) -AC_CHECK_FUNCS(setregid) +AC_CHECK_FUNCS(setreuid) AC_CHECK_FUNCS(setresgid) +AC_CHECK_FUNCS(setregid) AC_CHECK_FUNCS(initgroups) AC_CHECK_FUNCS(setgroups) -AC_CHECK_FUNCS(sigaction) -AC_CHECK_FUNCS(bsd_signal) AC_CHECK_TYPES(sighandler_t) dnl Solaris 8 has [u]intmax_t but not strtoumax(). How utterly braindamaged. diff --git a/tftp/main.c b/tftp/main.c index 438f48a..ac06330 100644 --- a/tftp/main.c +++ b/tftp/main.c @@ -305,7 +305,7 @@ int main(int argc, char *argv[]) sp->s_proto = (char *)"udp"; } - tftp_signal(SIGINT, intr); + tftp_signal(SIGINT, intr, 0); if (peerargc) { /* Set peer */ @@ -768,8 +768,8 @@ void intr(int sig) { (void)sig; /* Quiet unused warning */ - tftp_signal(SIGALRM, SIG_IGN); alarm(0); + tftp_signal(SIGALRM, SIG_DFL, 0); siglongjmp(toplevel, -1); } diff --git a/tftp/tftp.c b/tftp/tftp.c index aecdeb9..33a4175 100644 --- a/tftp/tftp.c +++ b/tftp/tftp.c @@ -84,7 +84,7 @@ void tftp_sendfile(int fd, const char *name, const char *mode) is_request = 1; /* First packet is the actual WRQ */ amount = 0; - tftp_signal(SIGALRM, timer); + tftp_signal(SIGALRM, timer, 0); do { if (is_request) { size = makerequest(WRQ, name, dp, mode) - 4; @@ -190,7 +190,7 @@ void tftp_recvfile(int fd, const char *name, const char *mode) firsttrip = 1; amount = 0; - tftp_signal(SIGALRM, timer); + tftp_signal(SIGALRM, timer, 0); do { if (firsttrip) { size = makerequest(RRQ, name, ap, mode); diff --git a/tftpd/misc.c b/tftpd/misc.c index 07684dd..9070f96 100644 --- a/tftpd/misc.c +++ b/tftpd/misc.c @@ -19,19 +19,11 @@ #include "tftpd.h" /* - * Set the signal handler and flags. Basically a user-friendly - * wrapper around sigaction(). + * Set the signal handler and flags, and error out on failure. */ -void set_signal(int signum, void (*handler) (int), int flags) +void set_signal(int signum, sighandler_t handler, int flags) { - struct sigaction sa; - - memset(&sa, 0, sizeof sa); - sa.sa_handler = handler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = flags; - - if (sigaction(signum, &sa, NULL)) { + if (tftp_signal(signum, handler, flags)) { syslog(LOG_ERR, "sigaction: %m"); exit(EX_OSERR); }