? o ? writev1.c Index: syslogd.c =================================================================== RCS file: /cvsroot/src/usr.sbin/syslogd/syslogd.c,v retrieving revision 1.107 diff -u -p -u -r1.107 syslogd.c --- syslogd.c 15 May 2012 01:22:50 -0000 1.107 +++ syslogd.c 5 Jun 2012 16:36:05 -0000 @@ -70,6 +70,7 @@ __RCSID("$NetBSD: syslogd.c,v 1.107 2012 * TLS, syslog-protocol, and syslog-sign code by Martin Schuette. */ #define SYSLOG_NAMES +#include <poll.h> #include "syslogd.h" #include "extern.h" @@ -266,6 +267,7 @@ void free_cred_SLIST(struct peer_cred_h static inline void free_incoming_tls_sockets(void); #endif /* !DISABLE_TLS */ +static int writev1(int, struct iovec *, size_t); /* for make_timestamp() */ #define TIMESTAMPBUFSIZE 35 @@ -1835,7 +1837,7 @@ logmsg(struct buf_msg *buffer) /* log the message to the particular outputs */ if (!Initialized) { f = &consfile; - f->f_file = open(ctty, O_WRONLY, 0); + f->f_file = open(ctty, O_WRONLY | O_NDELAY, 0); if (f->f_file >= 0) { DELREF(f->f_prevmsg); @@ -2404,7 +2406,8 @@ fprintlog(struct filed *f, struct buf_ms DPRINTF(D_MISC, "Logging to %s %s\n", TypeInfo[f->f_type].name, f->f_un.f_fname); again: - if (writev(f->f_file, iov, v - iov) < 0) { + if ((f->f_type == F_FILE ? writev(f->f_file, iov, v - iov) : + writev1(f->f_file, iov, v - iov)) < 0) { e = errno; if (f->f_type == F_FILE && e == ENOSPC) { int lasterror = f->f_lasterror; @@ -2419,7 +2422,7 @@ fprintlog(struct filed *f, struct buf_ms */ if ((e == EIO || e == EBADF) && f->f_type != F_FILE) { f->f_file = open(f->f_un.f_fname, - O_WRONLY|O_APPEND, 0); + O_WRONLY|O_APPEND|O_NDELAY, 0); if (f->f_file < 0) { f->f_type = F_UNUSED; logerror("%s", f->f_un.f_fname); @@ -3605,7 +3608,7 @@ cfline(size_t linenum, const char *line, const char *host) { struct addrinfo hints, *res; - int error, i, pri, syncfile; + int error, i, pri, syncfile, flags; const char *p, *q; char *bp; char buf[MAXLINE]; @@ -3819,19 +3822,22 @@ cfline(size_t linenum, const char *line, f->f_flags |= FFLAG_SIGN; #endif /* !DISABLE_SIGN */ (void)strlcpy(f->f_un.f_fname, p, sizeof(f->f_un.f_fname)); - if ((f->f_file = open(p, O_WRONLY|O_APPEND, 0)) < 0) { + if (isatty(f->f_file)) { + f->f_type = F_TTY; + if (strcmp(p, ctty) == 0) + f->f_type = F_CONSOLE; + flags = O_NDELAY; + } else { + f->f_type = F_FILE; + flags = 0; + } + if ((f->f_file = open(p, O_WRONLY|O_APPEND|flags, 0)) < 0) { f->f_type = F_UNUSED; logerror("%s", p); break; } if (syncfile) f->f_flags |= FFLAG_SYNC; - if (isatty(f->f_file)) - f->f_type = F_TTY; - else - f->f_type = F_FILE; - if (strcmp(p, ctty) == 0) - f->f_type = F_CONSOLE; break; case '|': @@ -4695,3 +4701,42 @@ copy_config_value_word(char **mem, const *p = ++q; return true; } + +static int +writev1(int fd, struct iovec *iov, size_t count) +{ + ssize_t nw = 0, tot = 0; + size_t ntries = 5; + + while (ntries--) { + switch ((nw = writev(fd, iov, count))) { + case -1: + if (errno == EAGAIN || errno == EWOULDBLOCK) { + struct pollfd pfd; + pfd.fd = fd; + pfd.events = POLLOUT; + pfd.revents = 0; + (void)poll(&pfd, 1, 500); + continue; + } else + return -1; + case 0: + return 0; + default: + tot += nw; + while (nw > 0) { + if (iov->iov_len > nw) { + iov->iov_len -= nw; + iov->iov_base += nw; + break; + } else { + if (count-- == 0) + return tot; + nw -= iov->iov_len; + iov++; + } + } + } + } + return tot == 0 ? nw : tot; +}