+/*************************************************
+* Write to an fd, retrying after signals *
+*************************************************/
+
+/* Basic write to fd for logs, handling EINTR.
+
+Arguments:
+ fd the fd to write to
+ buf the string to write
+ length the string length being written
+
+Returns:
+ length actually written, persisting an errno from write()
+*/
+ssize_t
+write_to_fd_buf(int fd, const uschar *buf, size_t length)
+{
+ssize_t wrote;
+size_t total_written = 0;
+const uschar *p = buf;
+size_t left = length;
+
+while (1)
+ {
+ wrote = write(fd, p, left);
+ if (wrote == (ssize_t)-1)
+ {
+ if (errno == EINTR) continue;
+ return wrote;
+ }
+ total_written += wrote;
+ if (wrote == left)
+ break;
+ else
+ {
+ p += wrote;
+ left -= wrote;
+ }
+ }
+return total_written;
+}
+
+
+/* Pull the file out of the configured or the compiled-in list.
+Called for an empty log_file_path element, for debug logging activation
+when file_path has not previously been set, and from the appenfile transport setup. */
+
+void
+set_file_path(BOOL *multiple)
+{
+uschar *s;
+int sep = ':'; /* Fixed separator - outside use */
+const uschar *ss = *log_file_path ? log_file_path : US LOG_FILE_PATH;
+
+if (*ss)
+ for (logging_mode = 0;
+ s = string_nextinlist(&ss, &sep, log_buffer, LOG_BUFFER_SIZE); )
+ {
+ if (Ustrcmp(s, "syslog") == 0)
+ logging_mode |= LOG_MODE_SYSLOG;
+ else if (!(logging_mode & LOG_MODE_FILE)) /* no file yet */
+ {
+ logging_mode |= LOG_MODE_FILE;
+ if (*s) file_path = string_copy(s); /* If a non-empty path is given, use it */
+ }
+ else if (multiple) *multiple = TRUE;
+ }
+else
+ logging_mode = LOG_MODE_FILE;
+
+/* Set up the ultimate default if necessary. */
+
+if (logging_mode & LOG_MODE_FILE && !*file_path)
+ if (LOG_FILE_PATH[0])
+ {
+ /* If we still do not have a file_path, we take
+ the first non-empty, non-syslog item in LOG_FILE_PATH, if there is
+ one. If there is no such item, use the ultimate default in the
+ spool directory. */
+
+ for (ss = US LOG_FILE_PATH;
+ s = string_nextinlist(&ss, &sep, log_buffer, LOG_BUFFER_SIZE);)
+ {
+ if (*s != '/') continue;
+ file_path = string_copy(s);
+ }
+ }
+ else file_path = string_sprintf("%s/log/%%slog", spool_directory);
+}
+
+
+void
+mainlog_close(void)
+{
+/* avoid closing it if it is closed already or if we do not see a chance
+to open the file mainlog later again */
+if (mainlogfd < 0 /* already closed */
+ || !(geteuid() == 0 || geteuid() == exim_uid))
+ return;
+(void)close(mainlogfd);
+mainlogfd = -1;
+mainlog_inode = 0;
+}
+