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
This commit is contained in:
Ben Gras 2013-06-10 23:47:42 +00:00
parent 1d71e39b73
commit 9178749e13
5 changed files with 102 additions and 33 deletions

View file

@ -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;
}

View file

@ -94,6 +94,8 @@
#include <time.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <net/netlib.h>
#include <net/hton.h>
@ -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];

View file

@ -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 <sys/ioctl.h>
#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

View file

@ -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) {

View file

@ -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);