Hi,
I think a daemon should run with non-blocking sockets. Especially
the upcoming tcp listen socket needs this. Replace the existing
fcntl(O_NONBLOCK) with the simpler SOCK_NONBLOCK and add it to the
receive sockets. React to EWOULDBLOCK although it should not happen.
ok?
bluhm
Index: usr.sbin/syslogd/syslogd.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.168
diff -u -p -r1.168 syslogd.c
--- usr.sbin/syslogd/syslogd.c 2 Jul 2015 16:24:48 -0000 1.168
+++ usr.sbin/syslogd/syslogd.c 2 Jul 2015 21:27:30 -0000
@@ -703,8 +703,8 @@ socket_bind(const char *proto, const cha
if (*fdp >= 0)
continue;
- if ((*fdp = socket(res->ai_family, res->ai_socktype,
- res->ai_protocol)) == -1)
+ if ((*fdp = socket(res->ai_family,
+ res->ai_socktype | SOCK_NONBLOCK, res->ai_protocol)) == -1)
continue;
if (getnameinfo(res->ai_addr, res->ai_addrlen, hostname,
@@ -784,7 +784,7 @@ udp_readcb(int fd, short event, void *ar
cvthname((struct sockaddr *)&sa, resolve, sizeof(resolve));
dprintf("cvthname res: %s\n", resolve);
printline(resolve, linebuf);
- } else if (n < 0 && errno != EINTR)
+ } else if (n < 0 && errno != EINTR && errno != EWOULDBLOCK)
logerror("recvfrom udp");
}
@@ -800,32 +800,23 @@ unix_readcb(int fd, short event, void *a
if (n > 0) {
linebuf[n] = '\0';
printline(LocalHostName, linebuf);
- } else if (n < 0 && errno != EINTR)
+ } else if (n < 0 && errno != EINTR && errno != EWOULDBLOCK)
logerror("recvfrom unix");
}
int
tcp_socket(struct filed *f)
{
- int s, flags;
+ int s;
char ebuf[ERRBUFSIZE];
- if ((s = socket(f->f_un.f_forw.f_addr.ss_family, SOCK_STREAM,
- IPPROTO_TCP)) == -1) {
+ if ((s = socket(f->f_un.f_forw.f_addr.ss_family,
+ SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP)) == -1) {
snprintf(ebuf, sizeof(ebuf), "socket \"%s\"",
f->f_un.f_forw.f_loghost);
logerror(ebuf);
return (-1);
}
- /* Connect must not block the process. */
- if ((flags = fcntl(s, F_GETFL)) == -1 ||
- fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1) {
- snprintf(ebuf, sizeof(ebuf), "fcntl \"%s\" O_NONBLOCK",
- f->f_un.f_forw.f_loghost);
- logerror(ebuf);
- close(s);
- return (-1);
- }
if (connect(s, (struct sockaddr *)&f->f_un.f_forw.f_addr,
f->f_un.f_forw.f_addr.ss_len) == -1 && errno != EINPROGRESS) {
snprintf(ebuf, sizeof(ebuf), "connect \"%s\"",
@@ -2453,10 +2444,9 @@ void
ctlsock_acceptcb(int fd, short event, void *arg)
{
struct event *ev = arg;
- int flags;
dprintf("Accepting control connection\n");
- fd = accept(fd, NULL, NULL);
+ fd = accept4(fd, NULL, NULL, SOCK_NONBLOCK);
if (fd == -1) {
if (errno != EINTR && errno != EWOULDBLOCK &&
errno != ECONNABORTED)
@@ -2470,13 +2460,6 @@ ctlsock_acceptcb(int fd, short event, vo
/* Only one connection at a time */
event_del(ev);
- if ((flags = fcntl(fd, F_GETFL)) == -1 ||
- fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
- logerror("fcntl ctlconn O_NONBLOCK");
- close(fd);
- return;
- }
-
fd_ctlconn = fd;
/* file descriptor has changed, reset event */
event_set(&ev_ctlread, fd_ctlconn, EV_READ|EV_PERSIST,
@@ -2523,6 +2506,8 @@ ctlconn_readcb(int fd, short event, void
case -1:
if (errno == EINTR)
goto retry;
+ if (errno == EWOULDBLOCK)
+ return;
logerror("ctlconn read");
/* FALLTHROUGH */
case 0:
@@ -2652,6 +2637,8 @@ ctlconn_writecb(int fd, short event, voi
case -1:
if (errno == EINTR)
goto retry;
+ if (errno == EWOULDBLOCK)
+ return;
if (errno != EPIPE)
logerror("ctlconn write");
/* FALLTHROUGH */