From: Timo Sirainen Date: Mon, 18 Jun 2018 14:03:01 +0000 (+0300) Subject: lib: When log writing keeps returning EAGAIN, change process title only once X-Git-Tag: 2.3.2.rc1~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8ffa9f26955f63c5f1152d579c5613a8c95760b5;p=thirdparty%2Fdovecot%2Fcore.git lib: When log writing keeps returning EAGAIN, change process title only once Otherwise each call will use up data stack memory. --- diff --git a/src/lib/failures.c b/src/lib/failures.c index 1b7f300440..078b0ed015 100644 --- a/src/lib/failures.c +++ b/src/lib/failures.c @@ -127,8 +127,11 @@ static int log_fd_write(int fd, const unsigned char *data, size_t len) ssize_t ret; unsigned int prev_signal_term_counter = signal_term_counter; unsigned int terminal_eintr_count = 0; + const char *old_title = NULL; + bool failed = FALSE, process_title_changed = FALSE; - while ((ret = write(fd, data, len)) != (ssize_t)len) { + while (!failed && + (ret = write(fd, data, len)) != (ssize_t)len) { if (ret > 0) { /* some was written, continue.. */ data += ret; @@ -138,7 +141,8 @@ static int log_fd_write(int fd, const unsigned char *data, size_t len) if (ret == 0) { /* out of disk space? */ errno = ENOSPC; - return -1; + failed = TRUE; + break; } switch (errno) { case EAGAIN: { @@ -152,17 +156,19 @@ static int log_fd_write(int fd, const unsigned char *data, size_t len) all the processes see the change. To avoid problems, we'll wait using poll() instead of changing the O_NONBLOCK flag. */ - const char *title, *old_title = - t_strdup(process_title_get()); - - if (old_title == NULL) - title = "[blocking on log write]"; - else - title = t_strdup_printf("%s - [blocking on log write]", - old_title); - process_title_set(title); + if (!process_title_changed) { + const char *title; + + process_title_changed = TRUE; + old_title = t_strdup(process_title_get()); + if (old_title == NULL) + title = "[blocking on log write]"; + else + title = t_strdup_printf("%s - [blocking on log write]", + old_title); + process_title_set(title); + } fd_wait_writable(fd); - process_title_set(old_title); break; } case EINTR: @@ -174,15 +180,19 @@ static int log_fd_write(int fd, const unsigned char *data, size_t len) } else { /* received two terminal signals. someone wants us dead. */ - return -1; + failed = TRUE; + break; } break; default: - return -1; + failed = TRUE; + break; } prev_signal_term_counter = signal_term_counter; } - return 0; + if (process_title_changed) + process_title_set(old_title); + return failed ? -1 : 0; } static int ATTR_FORMAT(3, 0)