summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2010-05-02 22:34:54 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2010-05-26 10:36:49 +0300
commit4f14a906311f8f650a12c8a697bc57a37f2096fa (patch)
treec575fdcce0abc846f0c235aa800d23898c8c4203
parent7cbbb4012d63c86e8e0726a5634bdd880ffe34b3 (diff)
downloadmailutils-4f14a906311f8f650a12c8a697bc57a37f2096fa.tar.gz
mailutils-4f14a906311f8f650a12c8a697bc57a37f2096fa.tar.bz2
Fix mailbox corruption in imap4d.
Delivery of a signal when a previous signal was being handled caused mailbox corruption. * imap4d/imap4d.c (imap4d_child_signal_setup): New function. (imap4d_mainloop): Call imap4d_child_signal_setup. * imap4d/signal.c (imap4d_child_signal): Reset all signal handlers before doing actual job. * lib/signal.c (mu_set_signals): Use sigaction.
-rw-r--r--imap4d/imap4d.c14
-rw-r--r--imap4d/signal.c18
-rw-r--r--lib/signal.c11
3 files changed, 30 insertions, 13 deletions
diff --git a/imap4d/imap4d.c b/imap4d/imap4d.c
index 195c4af4f..0b36a0068 100644
--- a/imap4d/imap4d.c
+++ b/imap4d/imap4d.c
@@ -383,18 +383,22 @@ get_client_address (int fd, struct sockaddr_in *pcs)
return 0;
}
+void
+imap4d_child_signal_setup (RETSIGTYPE (*handler) (int signo))
+{
+ static int sigtab[] = { SIGILL, SIGBUS, SIGFPE, SIGSEGV, SIGSTOP, SIGPIPE,
+ SIGABRT, SIGINT, SIGQUIT, SIGTERM, SIGHUP, SIGALRM };
+ mu_set_signals (handler, sigtab, MU_ARRAY_SIZE (sigtab));
+}
+
static int
imap4d_mainloop (int fd, FILE *infile, FILE *outfile)
{
imap4d_tokbuf_t tokp;
char *text;
int debug_mode = isatty (fd);
- static int sigtab[] = { SIGILL, SIGBUS, SIGFPE, SIGSEGV, SIGSTOP, SIGPIPE,
- SIGABRT, SIGINT, SIGQUIT, SIGTERM, SIGHUP, SIGALRM };
- /* Reset signals */
- mu_set_signals (imap4d_child_signal, sigtab, MU_ARRAY_SIZE (sigtab));
-
+ imap4d_child_signal_setup (imap4d_child_signal);
util_setio (infile, outfile);
if (imap4d_preauth_setup (fd) == 0)
diff --git a/imap4d/signal.c b/imap4d/signal.c
index c9dcfc56d..d71138e18 100644
--- a/imap4d/signal.c
+++ b/imap4d/signal.c
@@ -49,21 +49,25 @@ imap4d_master_signal (int signo)
RETSIGTYPE
imap4d_child_signal (int signo)
{
+ imap4d_child_signal_setup (SIG_IGN);
mu_diag_output (MU_DIAG_CRIT, _("got signal `%s'"), strsignal (signo));
-
switch (signo)
{
case SIGTERM:
case SIGHUP:
- imap4d_bye (ERR_TERMINATE);
-
+ signo = ERR_TERMINATE;
+ break;
+
case SIGALRM:
- imap4d_bye (ERR_TIMEOUT);
-
+ signo = ERR_TIMEOUT;
+ break;
+
case SIGPIPE:
- imap4d_bye (ERR_NO_OFILE);
+ signo = ERR_NO_OFILE;
+ break;
default:
- imap4d_bye (ERR_SIGNAL);
+ signo = ERR_SIGNAL;
}
+ imap4d_bye (signo);
}
diff --git a/lib/signal.c b/lib/signal.c
index 8f5b61564..8ce21080a 100644
--- a/lib/signal.c
+++ b/lib/signal.c
@@ -26,7 +26,16 @@ void
mu_set_signals (RETSIGTYPE (*handler) (int signo), int *sigv, int sigc)
{
int i;
+ struct sigaction act;
+ act.sa_flags = 0;
+ sigemptyset (&act.sa_mask);
for (i = 0; i < sigc; i++)
- signal (sigv[i], handler);
+ sigaddset (&act.sa_mask, i);
+
+ for (i = 0; i < sigc; i++)
+ {
+ act.sa_handler = handler;
+ sigaction (sigv[i], &act, NULL);
+ }
}

Return to:

Send suggestions and report system problems to the System administrator.