/* Copyright (c) The Exim Maintainers 2020 - 2022 */
/* Copyright (c) University of Cambridge 1995 - 2018 */
/* See the file NOTICE for conditions of use and distribution. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Functions for writing log files. The code for maintaining datestamped
log files was originally contributed by Tony Sheen. */
length actually written, persisting an errno from write()
*/
ssize_t
-write_to_fd_buf(int fd, const uschar *buf, size_t length)
+write_to_fd_buf(int fd, const uschar * buf, size_t length)
{
ssize_t wrote;
size_t total_written = 0;
-const uschar *p = buf;
+const uschar * p = buf;
size_t left = length;
while (1)
return total_written;
}
+static inline ssize_t
+write_gstring_to_fd_buf(int fd, const gstring * g)
+{
+return write_to_fd_buf(fd, g->s, g->ptr);
+}
+
static void
{
int paniclogfd;
ssize_t written_len;
-gstring gs = { .size = LOG_BUFFER_SIZE-1, .ptr = 0, .s = log_buffer };
+gstring gs = { .size = LOG_BUFFER_SIZE-2, .ptr = 0, .s = log_buffer };
gstring * g;
va_list ap;
}
va_end(ap);
- g->size = LOG_BUFFER_SIZE;
- g = string_catn(g, US"\n", 1);
- debug_printf("%s", string_from_gstring(g));
+ debug_printf("%Y\n", g);
- gs.size = LOG_BUFFER_SIZE-1; /* Having used the buffer for debug output, */
+ gs.size = LOG_BUFFER_SIZE-2; /* Having used the buffer for debug output, */
gs.ptr = 0; /* reset it for the real use. */
gs.s = log_buffer;
}
if (!syslog_pid) pid_position[1] = g->ptr; /* … and end+1 of the PID */
}
-if (f.really_exim && message_id[0] != 0)
+if (f.really_exim && message_id[0])
g = string_fmt_append(g, "%s ", message_id);
if (flags & LOG_CONFIG)
}
}
+/* actual size, now we are placing the newline (and space for NUL) */
+gs.size = LOG_BUFFER_SIZE;
g = string_catn(g, US"\n", 1);
string_from_gstring(g);
/* Failing to write to the log is disastrous */
- written_len = write_to_fd_buf(mainlogfd, g->s, g->ptr);
+ written_len = write_gstring_to_fd_buf(mainlogfd, g);
if (written_len != g->ptr)
{
log_write_failed(US"main log", g->ptr, written_len);
g = g2;
else /* Buffer is full; truncate */
{
- g->ptr -= 100; /* For message and separator */
- if (g->s[g->ptr-1] == '\n') g->ptr--;
+ gstring_trim(g, 100); /* For message and separator */
+ gstring_trim_trailing(g, '\n');
g = string_cat(g, US"\n*** truncated ***\n");
break;
}
if (fstat(rejectlogfd, &statbuf) >= 0) rejectlog_inode = statbuf.st_ino;
}
- written_len = write_to_fd_buf(rejectlogfd, g->s, g->ptr);
+ written_len = write_gstring_to_fd_buf(rejectlogfd, g);
if (written_len != g->ptr)
{
log_write_failed(US"reject log", g->ptr, written_len);
if (panic_save_buffer)
(void) write(paniclogfd, panic_save_buffer, Ustrlen(panic_save_buffer));
- written_len = write_to_fd_buf(paniclogfd, g->s, g->ptr);
+ written_len = write_gstring_to_fd_buf(paniclogfd, g);
if (written_len != g->ptr)
{
int save_errno = errno;
/* Give up if the DIE flag is set */
if ((flags & LOG_PANIC_DIE) != LOG_PANIC)
- die(NULL, US"Unexpected failure, please try later");
+ if (panic_coredump)
+ kill(getpid(), SIGSEGV); /* deliberate trap */
+ else
+ die(NULL, US"Unexpected failure, please try later");
}
}
void
debug_logging_stop(BOOL kill)
{
+debug_printf("debug terminated by %s\n", kill ? "kill" : "stop");
debug_pretrigger_discard();
if (!debug_file || !debuglog_name[0]) return;