summaryrefslogtreecommitdiff
path: root/gnu/dist/postfix/src/util/msg.c
diff options
context:
space:
mode:
authorrpaulo <rpaulo@NetBSD.org>2006-12-21 02:27:16 +0000
committerrpaulo <rpaulo@NetBSD.org>2006-12-21 02:27:16 +0000
commit0225a7dd90a5c990ec79a8f3260e377c5fddfbe3 (patch)
treede7487176ba6a3b847134afd4f6990ce6123b46f /gnu/dist/postfix/src/util/msg.c
parent610c0515b70335201b523e2787be27816bf7de3b (diff)
postfix-2.3.5
Diffstat (limited to 'gnu/dist/postfix/src/util/msg.c')
-rw-r--r--gnu/dist/postfix/src/util/msg.c62
1 files changed, 54 insertions, 8 deletions
diff --git a/gnu/dist/postfix/src/util/msg.c b/gnu/dist/postfix/src/util/msg.c
index 545c9c6c9da..bf4881dc26b 100644
--- a/gnu/dist/postfix/src/util/msg.c
+++ b/gnu/dist/postfix/src/util/msg.c
@@ -1,4 +1,4 @@
-/* $NetBSD: msg.c,v 1.1.1.4 2006/07/19 01:17:53 rpaulo Exp $ */
+/* $NetBSD: msg.c,v 1.1.1.5 2006/12/21 02:35:05 rpaulo Exp $ */
/*++
/* NAME
@@ -41,7 +41,7 @@
/* to the standard error stream, but the disposition can be changed
/* by the user. See the hints below in the SEE ALSO section.
/*
-/* msg_info(), msg_warn(), msg_error(), msg_fatal() and msg_panic()
+/* msg_info(), msg_warn(), msg_error(), msg_fatal*() and msg_panic()
/* produce a one-line record with the program name, a severity code
/* (except for msg_info()), and an informative message. The program
/* name must have been set by calling one of the msg_XXX_init()
@@ -74,6 +74,40 @@
/* msg_verbose is a global flag that can be set to make software
/* more verbose about what it is doing. By default the flag is zero.
/* By convention, a larger value means more noise.
+/* REENTRANCY
+/* .ad
+/* .fi
+/* The msg_info() etc. output routines are protected against
+/* ordinary recursive calls and against re-entry by signal
+/* handlers.
+/*
+/* Protection against re-entry by signal handlers is subject
+/* to the following limitations:
+/* .IP \(bu
+/* The signal handlers must never return. In other words, the
+/* signal handlers must do one or more of the following: call
+/* _exit(), kill the process with a signal, and permanently block
+/* the process.
+/* .IP \(bu
+/* The signal handlers must invoke msg_info() etc. not until
+/* after the msg_XXX_init() functions complete initialization,
+/* and not until after the first formatted output to a VSTRING
+/* or VSTREAM.
+/* .IP \(bu
+/* Each msg_cleanup() call-back function, and each Postfix or
+/* system function invoked by that call-back function, either
+/* protects itself against recursive calls and re-entry by a
+/* terminating signal handler, or is called exclusively by the
+/* msg(3) module.
+/* .PP
+/* When re-entrancy is detected, the requested output and
+/* optional cleanup operations are skipped. Skipping the output
+/* operations prevents memory corruption of VSTREAM_ERR data
+/* structures, and prevents deadlock on Linux releases that
+/* use mutexes within system library routines such as syslog().
+/* This protection exists under the condition that these
+/* specific resources are accessed exclusively via the msg_info()
+/* etc. functions.
/* SEE ALSO
/* msg_output(3) specify diagnostics disposition
/* msg_stdio(3) direct diagnostics to standard I/O stream
@@ -120,14 +154,23 @@
int msg_verbose = 0;
/*
- * Private state. The msg_exiting flag prevents us from recursively
- * reporting an error.
+ * Private state.
*/
static MSG_CLEANUP_FN msg_cleanup_fn = 0;
-static int msg_exiting = 0;
static int msg_error_count = 0;
static int msg_error_bound = 13;
+ /*
+ * The msg_exiting flag prevents us from recursively reporting an error with
+ * msg_fatal*() or msg_panic(), and provides a first-level safety net for
+ * optional cleanup actions against signal handler re-entry problems. Note
+ * that msg_vprintf() implements its own guard against re-entry.
+ *
+ * XXX We specify global scope, to discourage the compiler from doing smart
+ * things.
+ */
+volatile int msg_exiting = 0;
+
/* msg_info - report informative message */
void msg_info(const char *fmt,...)
@@ -177,7 +220,8 @@ NORETURN msg_fatal(const char *fmt,...)
msg_cleanup_fn();
}
sleep(1);
- exit(1);
+ /* In case we're running as a signal handler. */
+ _exit(1);
}
/* msg_fatal_status - report error and terminate gracefully */
@@ -194,7 +238,8 @@ NORETURN msg_fatal_status(int status, const char *fmt,...)
msg_cleanup_fn();
}
sleep(1);
- exit(status);
+ /* In case we're running as a signal handler. */
+ _exit(status);
}
/* msg_panic - report error and dump core */
@@ -210,7 +255,8 @@ NORETURN msg_panic(const char *fmt,...)
}
sleep(1);
abort(); /* Die! */
- exit(1); /* DIE!! */
+ /* In case we're running as a signal handler. */
+ _exit(1); /* DIE!! */
}
/* msg_cleanup - specify cleanup routine */