diff options
author | Bruce Guenter <bruce@untroubled.org> | 2007-04-10 00:03:25 +0000 |
---|---|---|
committer | Bruce Guenter <bruce@untroubled.org> | 2007-04-10 00:03:25 +0000 |
commit | 0c747e5e565256cd911dfaec96db8c188c462eb7 (patch) | |
tree | 308402af05d2b0b2feb5b36ac3b54b8ea2e9c056 /lib | |
parent | 2971ceacb9ccd75126996669a0ed92e8b9a6dc8e (diff) |
Added a send timeout in nullmailer-send, to kill sending messages that
stall.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.am | 1 | ||||
-rw-r--r-- | lib/selfpipe.cc | 101 | ||||
-rw-r--r-- | lib/selfpipe.h | 16 |
3 files changed, 118 insertions, 0 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am index d39807a..102d9e5 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -16,6 +16,7 @@ libmisc_a_SOURCES = \ itoa.h itoa.cc \ makefield.cc \ netstring.h netstring.cc \ + selfpipe.cc selfpipe.h \ setenv.cc setenv.h libnullmailer_a_SOURCES = diff --git a/lib/selfpipe.cc b/lib/selfpipe.cc new file mode 100644 index 0000000..e8e9cc1 --- /dev/null +++ b/lib/selfpipe.cc @@ -0,0 +1,101 @@ +// nullmailer -- a simple relay-only MTA +// Copyright (C) 2007 Bruce Guenter <bruce@untroubled.org> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// You can contact me at <bruce@untroubled.org>. There is also a mailing list +// available to discuss this package. To subscribe, send an email to +// <nullmailer-subscribe@lists.untroubled.org>. + +#include <sys/types.h> +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <unistd.h> +#include "selfpipe.h" + +static int fds[2] = { -1, -1 }; + +static int fcntl_fl_on(int fd, int flag) +{ + int flags; + int newflags; + if ((flags = fcntl(fd, F_GETFL, 0)) == -1) + return 0; + if ((newflags = flags | flag) != flags) + if (fcntl(fd, F_SETFL, newflags)) + return 0; + return 1; +} + +selfpipe::selfpipe() +{ + if (fds[0] < 0) { + if (pipe(fds) != -1) { + if (fcntl_fl_on(fds[0], O_NONBLOCK) + && fcntl_fl_on(fds[1], O_NONBLOCK) + && fcntl_fl_on(fds[1], FD_CLOEXEC) + && fcntl_fl_on(fds[1], FD_CLOEXEC)) + return; + + close(fds[0]); + close(fds[1]); + } + fds[0] = fds[1] = -1; + } +} + +selfpipe::operator bool() const +{ + return fds[0] >= 0; +} + +static void catcher(int sig) +{ + signal(sig, catcher); + write(fds[1], &sig, sizeof sig); +} + +void selfpipe::catchsig(int sig) +{ + signal(sig, catcher); +} + +int selfpipe::caught() +{ + int buf; + if (read(fds[0], &buf, sizeof buf) == sizeof buf) + return buf; + return 0; +} + +int selfpipe::waitsig(int timeout) +{ + fd_set fdset; + FD_ZERO(&fdset); + FD_SET(fds[0], &fdset); + struct timeval tv; + tv.tv_sec = timeout; + tv.tv_usec = 0; + int s; + while ((s = select(fds[0] + 1, &fdset, 0, 0, + (timeout <= 0) ? 0 : &tv)) == -1) { + if (errno != EINTR) + return -1; + } + if (s == 1) + return caught(); + return 0; +} diff --git a/lib/selfpipe.h b/lib/selfpipe.h new file mode 100644 index 0000000..1ad2136 --- /dev/null +++ b/lib/selfpipe.h @@ -0,0 +1,16 @@ +#ifndef NULLMAILER_SELFPIPE__H__ +#define NULLMAILER_SELFPIPE__H__ + +class selfpipe +{ + public: + selfpipe(); + + operator bool() const; + + void catchsig(int sig); + int caught(); + int waitsig(int timeout = 0); +}; + +#endif // NULLMAILER_SELFPIPE__H__ |