dovecot: If log flushing fails because of EINTR or EAGAIN, handl...

dovecot at dovecot.org dovecot at dovecot.org
Mon Jul 16 01:23:21 EEST 2007


details:   http://hg.dovecot.org/dovecot/rev/23460b525442
changeset: 6026:23460b525442
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Jul 16 01:10:13 2007 +0300
description:
If log flushing fails because of EINTR or EAGAIN, handle them instead of
exiting.

diffstat:

1 file changed, 33 insertions(+), 4 deletions(-)
src/lib/failures.c |   37 +++++++++++++++++++++++++++++++++----

diffs (82 lines):

diff -r 001d25a650df -r 23460b525442 src/lib/failures.c
--- a/src/lib/failures.c	Mon Jul 16 00:28:24 2007 +0300
+++ b/src/lib/failures.c	Mon Jul 16 01:10:13 2007 +0300
@@ -1,6 +1,7 @@
 /* Copyright (c) 2002-2003 Timo Sirainen */
 
 #include "lib.h"
+#include "ioloop.h"
 #include "str.h"
 #include "backtrace-string.h"
 #include "printf-format-fix.h"
@@ -135,6 +136,34 @@ default_panic_handler(const char *format
 	abort();
 }
 
+static void log_fd_flush_stop(struct ioloop *ioloop)
+{
+	io_loop_stop(ioloop);
+}
+
+static int log_fd_flush(FILE *fd)
+{
+	struct ioloop *ioloop;
+	struct io *io;
+
+	while (fflush(fd) < 0) {
+		if (errno == EINTR)
+			continue;
+		if (errno != EAGAIN)
+			return -1;
+
+		/* wait until we can write more. this can happen at least
+		   when writing to terminal, even if fd is blocking. */
+		ioloop = io_loop_create();
+		io = io_add(IO_WRITE, fileno(log_fd),
+			    log_fd_flush_stop, ioloop);
+		io_loop_run(ioloop);
+		io_remove(&io);
+		io_loop_destroy(&ioloop);
+	}
+	return 0;
+}
+
 static void __attr_format__(2, 0)
 default_fatal_handler(int status, const char *format, va_list args)
 {
@@ -142,7 +171,7 @@ default_fatal_handler(int status, const 
 	    status == FATAL_DEFAULT)
 		status = FATAL_LOGERROR;
 
-	if (fflush(log_fd) < 0 && status == FATAL_DEFAULT)
+	if (log_fd_flush(log_fd) < 0 && status == FATAL_DEFAULT)
 		status = FATAL_LOGWRITE;
 
 	failure_exit(status);
@@ -154,7 +183,7 @@ default_error_handler(const char *format
 	if (default_handler("Error: ", log_fd, format, args) < 0)
 		failure_exit(FATAL_LOGERROR);
 
-	if (fflush(log_fd) < 0)
+	if (log_fd_flush(log_fd) < 0)
 		failure_exit(FATAL_LOGWRITE);
 }
 
@@ -163,7 +192,7 @@ default_warning_handler(const char *form
 {
 	(void)default_handler("Warning: ", log_fd, format, args);
 
-	if (fflush(log_fd) < 0)
+	if (log_fd_flush(log_fd) < 0)
 		failure_exit(FATAL_LOGWRITE);
 }
 
@@ -172,7 +201,7 @@ default_info_handler(const char *format,
 {
 	(void)default_handler("Info: ", log_info_fd, format, args);
 
-	if (fflush(log_info_fd) < 0)
+	if (log_fd_flush(log_info_fd) < 0)
 		failure_exit(FATAL_LOGWRITE);
 }
 


More information about the dovecot-cvs mailing list