From 9178749e131d3ea6caf57051fd87554e51126441 Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Mon, 10 Jun 2013 23:47:42 +0000 Subject: [PATCH] libc syslog, syslogd, logger, uds fixes changes necessary for libc syslog() using a unix domain socket. . libc syslog: don't use send() connect() for unix datagram sockets, minix wants write() and ioctl() . syslogd: listen on _PATH_LOG unix domain socket . logger: warnings fixes . pfs: make uds dgram socket type nonblocking so syslog() doesn't block . vfs: add sanity check for empty fd in unpause() Change-Id: Ied136c6fe0cc288f5a53478f1eebccc1ab1f39fb --- commands/logger/logger.c | 8 ++-- commands/syslogd/syslogd.c | 89 ++++++++++++++++++++++++++++---------- lib/libc/gen/syslog.c | 16 ++++++- servers/pfs/dev_uds.c | 17 +++++--- servers/vfs/pipe.c | 5 +++ 5 files changed, 102 insertions(+), 33 deletions(-) diff --git a/commands/logger/logger.c b/commands/logger/logger.c index 39a2dbfa8..eadb58616 100644 --- a/commands/logger/logger.c +++ b/commands/logger/logger.c @@ -160,11 +160,11 @@ int main(int argc, char **argv) len = strlen(*argv); if (p + len < endp && p > buf) { *--p = '\0'; - syslog(pri, buf); + syslog(pri, "%s", buf); p = buf; } if (len > sizeof(buf) - 1) { - syslog(pri, *argv++); + syslog(pri, "%s", *argv++); if (!--argc) break; } else { memcpy(p, *argv++, len); @@ -176,10 +176,10 @@ int main(int argc, char **argv) } if (p != buf) { *p = '\0'; - syslog(pri, buf); + syslog(pri, "%s", buf); } } else /* Main loop */ - while (fgets(buf, sizeof(buf), stdin) != NULL) syslog(pri, buf); + while (fgets(buf, sizeof(buf), stdin) != NULL) syslog(pri, "%s", buf); return EXIT_SUCCESS; } diff --git a/commands/syslogd/syslogd.c b/commands/syslogd/syslogd.c index 21b5437c8..636dcad16 100644 --- a/commands/syslogd/syslogd.c +++ b/commands/syslogd/syslogd.c @@ -94,6 +94,8 @@ #include #include #include +#include +#include #include #include #include @@ -330,7 +332,7 @@ void logmsg(int pri, char *msg, char *from, int flags) !strcmp(from, f->f_prevhost)) { strncpy(f->f_lasttime, timestamp, 15); f->f_prevcount += 1; - DEBUG(dprintf("msg repeated %d times, %ld sec of %d\n", + DEBUG(dprintf("msg repeated %d times, %d sec of %d\n", f->f_prevcount, now - f->f_time, repeatinterval[f->f_repeatcount]);) /* If domark would have logged this by now, @@ -694,6 +696,7 @@ void init(int sig) DEBUG ( if (DbgOpt) { for (fLog = Files; fLog; fLog = fLog->f_next) { + int i; for (i = 0; i <= LOG_NFACILITIES; i += 1) if (fLog->f_pmask[i] == INTERNAL_NOPRI) printf("X "); @@ -774,6 +777,34 @@ void daemonize(char *line) return; } +int sockread(int *fd, char *buf, int maxlen) +{ + int len; + + /* Read a message from application programs */ + len = read(*fd, buf, maxlen); + if (len > 0) { /* Got a message */ + buf[len] = '\0'; + dprintf("got a message (%d, %#x)\n", *fd, len); + printline(LocalHostName, buf); + + } else if (len < 0) { /* Got an error or signal while reading */ + if (errno != EINTR) /* */ + { + logerror("Receive error from UDP channel"); + close(*fd); + *fd= -1; + } + + } else { /* (len == 0) Channel has been closed */ + logerror("network channel has closed"); + close(*fd); + die(-1); + } + + return len; +} + /* ** Name: int main(int argc, char **argv); ** Function: Syslog daemon entry point @@ -782,6 +813,7 @@ int main(int argc, char **argv) { char *p, *udpdev, *eol; int nfd, kfd, len, fdmax; + int ufd; int ch, port = 0; fd_set fdset; struct nwio_udpopt udpopt; @@ -863,7 +895,27 @@ int main(int argc, char **argv) return EXIT_FAILURE; } - fdmax = max(nfd, kfd) + 1; + /* Open unix domain socket */ + + if((ufd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) { + perror("unix socket"); + } else { + struct sockaddr_un uaddr; + memset(&uaddr, 0, sizeof(uaddr)); + strncpy(uaddr.sun_path, _PATH_LOG, sizeof(uaddr.sun_path) - 1); + uaddr.sun_family = AF_UNIX; + if(bind(ufd, (struct sockaddr *) &uaddr, sizeof(uaddr)) < 0) { + perror("unix socket bind"); + close(ufd); + ufd = -1; + } + } + + if(ufd < 0) exit(1); + + DEBUG(dprintf("unix domain socket = %d, at %s....\n", ufd, _PATH_LOG);) + + fdmax = max(max(nfd, kfd), ufd) + 1; DEBUG(dprintf("off & running....\n");) @@ -874,35 +926,26 @@ int main(int argc, char **argv) FD_ZERO(&fdset); /* Setup descriptors for select */ if(nfd >= 0) FD_SET(nfd, &fdset); if(kfd >= 0) FD_SET(kfd, &fdset); + if(ufd >= 0) FD_SET(ufd, &fdset); + + dprintf("select: nfd = %d, ufd = %d, fdmax = %d\n", nfd, ufd, fdmax); if (select(fdmax, &fdset, NULL, NULL, NULL) <= 0) { sleep(1); continue; } + if (nfd >= 0 && FD_ISSET(nfd, &fdset)) { - - /* Read a message from application programs */ - len = read(nfd, line, MAXLINE); - if (len > 0) { /* Got a message */ - line[len] = '\0'; - dprintf("got a message (%d, %#x)\n", nfd, len); - printline(LocalHostName, line); - - } else if (len < 0) { /* Got an error or signal while reading */ - if (errno != EINTR) /* */ - { - logerror("Receive error from UDP channel"); - close(nfd); - nfd= -1; - } - - } else { /* (len == 0) Channel has been closed */ - logerror("UDP channel has closed"); - close(nfd); - die(-1); - } + dprintf("got nfd message (%d)\n", nfd); + len = sockread(&nfd, line, MAXLINE); } + + if (ufd >= 0 && FD_ISSET(ufd, &fdset)) { + dprintf("got ufd message (%d)\n", ufd); + len = sockread(&ufd, line, MAXLINE); + } + if (kfd >= 0 && FD_ISSET(kfd, &fdset)) { static char linebuf[5*1024]; diff --git a/lib/libc/gen/syslog.c b/lib/libc/gen/syslog.c index 971710387..8febd8969 100644 --- a/lib/libc/gen/syslog.c +++ b/lib/libc/gen/syslog.c @@ -59,6 +59,10 @@ __RCSID("$NetBSD: syslog.c,v 1.53 2012/10/11 17:09:55 christos Exp $"); #include "reentrant.h" #include "extern.h" +#ifdef __minix +#include +#endif + #ifdef __weak_alias __weak_alias(closelog,_closelog) __weak_alias(openlog,_openlog) @@ -448,7 +452,11 @@ vsyslogp_r(int pri, struct syslog_data *data, const char *msgid, * to give syslogd a chance to empty its socket buffer. */ for (tries = 0; tries < MAXTRIES; tries++) { +#ifdef __minix + if (write(data->log_file, tbuf, cnt) != -1) +#else if (send(data->log_file, tbuf, cnt, 0) != -1) +#endif break; if (errno != ENOBUFS) { disconnectlog_r(data); @@ -517,9 +525,15 @@ connectlog_r(struct syslog_data *data) data->log_connected = 0; } if (!data->log_connected) { +#ifdef __minix + if(ioctl(data->log_file, NWIOSUDSTADDR, (void *) &sun) < 0) + +#else if (connect(data->log_file, (const struct sockaddr *)(const void *)&sun, - (socklen_t)sizeof(sun)) == -1) { + (socklen_t)sizeof(sun)) == -1) +#endif + { (void)close(data->log_file); data->log_file = -1; } else diff --git a/servers/pfs/dev_uds.c b/servers/pfs/dev_uds.c index 1d05f7217..cada761a5 100644 --- a/servers/pfs/dev_uds.c +++ b/servers/pfs/dev_uds.c @@ -579,14 +579,21 @@ static int uds_perform_write(int minor, endpoint_t m_source, return EPIPE; } + /* we have to preserve the boundary for DGRAM. if there's + * already a packet waiting, discard it silently and pretend + * it was written. + */ + if(uds_fd_table[minor].type == SOCK_DGRAM && + uds_fd_table[peer].size > 0) { + return size; + } + /* check if write would overrun buffer. check if message - * boundry preserving types (SEQPACKET and DGRAM) wouldn't write - * to an empty buffer. check if connectionless sockets have a - * target to write to. + * SEQPACKET wouldn't write to an empty buffer. check if + * connectionless sockets have a target to write to. */ if ((uds_fd_table[peer].pos+uds_fd_table[peer].size+size > PIPE_BUF) || - ((uds_fd_table[minor].type == SOCK_SEQPACKET || - uds_fd_table[minor].type == SOCK_DGRAM) && + ((uds_fd_table[minor].type == SOCK_SEQPACKET) && uds_fd_table[peer].size > 0)) { if (pretend) { diff --git a/servers/vfs/pipe.c b/servers/vfs/pipe.c index 7870d7ae1..f9a4cfb3c 100644 --- a/servers/vfs/pipe.c +++ b/servers/vfs/pipe.c @@ -604,6 +604,11 @@ void unpause(endpoint_t proc_e) if (fild < 0 || fild >= OPEN_MAX) panic("file descriptor out-of-range"); f = rfp->fp_filp[fild]; + if(!f) { + sys_sysctl_stacktrace(rfp->fp_endpoint); + panic("process %d blocked on empty fd %d", + rfp->fp_endpoint, fild); + } dev = (dev_t) f->filp_vno->v_sdev; /* device hung on */ major_dev = major(dev); minor_dev = minor(dev);