From 209df1f20e34620e6d970358b343af10e90800be Mon Sep 17 00:00:00 2001 From: Matthias Andree Date: Mon, 14 Aug 2006 00:58:00 +0000 Subject: Ignore SIGPIPE, EPIPE must suffice as error. Calling longjmp() from a signal handler is unsafe. svn path=/branches/BRANCH_6-3/; revision=4893 --- NEWS | 3 +++ driver.c | 27 +++++---------------------- 2 files changed, 8 insertions(+), 22 deletions(-) diff --git a/NEWS b/NEWS index 8a733bae..6d8f922a 100644 --- a/NEWS +++ b/NEWS @@ -104,6 +104,9 @@ fetchmail 6.3.5 (not yet released): now reported to the TTY where fetchmail was started from. * fetchmail now complains and aborts when it cannot properly daemonize itself. * fix compilation on systems that don't know struct addrinfo (Solaris 2.6). +* ignore SIGPIPE signals and rely on functions to return EPIPE instead. This is + necessary because the former longjmp() from the signal handler is unsafe and + makes the whole fetchmail behavior undefined after the event. # CHANGES: * Rename all fetchmail-internal lock_* functions to fm_lock_*. Obsoletes diff --git a/driver.c b/driver.c index c1d38a41..ae4b7e69 100644 --- a/driver.c +++ b/driver.c @@ -55,7 +55,6 @@ /* throw types for runtime errors */ #define THROW_TIMEOUT 1 /* server timed out */ -#define THROW_SIGPIPE 2 /* SIGPIPE on stream socket */ /* magic values for the message length array */ #define MSGLEN_UNKNOWN 0 /* length unknown (0 is impossible) */ @@ -110,18 +109,14 @@ static RETSIGTYPE timeout_handler (int signal) (void)signal; if(stage != STAGE_IDLE) { timeoutcount++; + /* XXX FIXME: this siglongjmp must die - it's not safe to be + * called from a function handler and breaks, for instance, + * getaddrinfo() */ siglongjmp(restart, THROW_TIMEOUT); } else idletimeout = 1; } -static RETSIGTYPE sigpipe_handler (int signal) -/* handle SIGPIPE signal indicating a broken stream socket */ -{ - (void)signal; - siglongjmp(restart, THROW_SIGPIPE); -} - #define CLEANUP_TIMEOUT 60 /* maximum timeout during cleanup */ static int cleanupSockClose (int fd) @@ -845,7 +840,6 @@ static int do_session( int tmperr; int deletions = 0, js; const char *msg; - SIGHANDLERTYPE pipesave; SIGHANDLERTYPE alrmsave; ctl->server.base_protocol = proto; @@ -859,9 +853,6 @@ static int do_session( alrmsave = set_signal_handler(SIGALRM, timeout_handler); mytimeout = ctl->server.timeout; - /* set up the broken-pipe timeout */ - pipesave = set_signal_handler(SIGPIPE, sigpipe_handler); - if ((js = sigsetjmp(restart,1))) { /* exception caught */ @@ -878,14 +869,7 @@ static int do_session( freeaddrinfo(ai1); ai1 = NULL; } - if (js == THROW_SIGPIPE) - { - set_signal_handler(SIGPIPE, SIG_IGN); - report(stdout, - GT_("SIGPIPE thrown from an MDA or a stream socket error\n")); - wait(0); - } - else if (js == THROW_TIMEOUT) + if (js == THROW_TIMEOUT) { if (phase == OPEN_WAIT) report(stdout, @@ -939,7 +923,7 @@ static int do_session( } else { - /* setjmp returned zero -> normal operation */ + /* sigsetjmp returned zero -> normal operation */ char buf[MSGBUFSIZE+1], *realhost; int count, newm, bytes; int fetches, dispatches, oldphase; @@ -1581,7 +1565,6 @@ closeUp: set_timeout(0); /* cancel any pending alarm */ set_signal_handler(SIGALRM, alrmsave); - set_signal_handler(SIGPIPE, pipesave); return(err); } -- cgit v1.2.3