- FD_ZERO(&fds);
- FD_SET(sock_fd, &fds);
-
- if (select(sock_fd + 1, &fds, NULL, NULL, NULL) < 0) {
- if (errno == EINTR) {
- /* alarm may have happened */
- continue;
- }
- bb_perror_msg_and_die("select");
+ ssize_t sz;
+
+#if ENABLE_FEATURE_SYSLOGD_DUP
+ last_buf = recvbuf;
+ if (recvbuf == G.recvbuf)
+ recvbuf = G.recvbuf + MAX_READ;
+ else
+ recvbuf = G.recvbuf;
+#endif
+ read_again:
+ sz = safe_read(sock_fd, recvbuf, MAX_READ - 1);
+ if (sz < 0)
+ bb_perror_msg_and_die("read from /dev/log");
+
+ /* Drop trailing '\n' and NULs (typically there is one NUL) */
+ while (1) {
+ if (sz == 0)
+ goto read_again;
+ /* man 3 syslog says: "A trailing newline is added when needed".
+ * However, neither glibc nor uclibc do this:
+ * syslog(prio, "test") sends "test\0" to /dev/log,
+ * syslog(prio, "test\n") sends "test\n\0".
+ * IOW: newline is passed verbatim!
+ * I take it to mean that it's syslogd's job
+ * to make those look identical in the log files. */
+ if (recvbuf[sz-1] != '\0' && recvbuf[sz-1] != '\n')
+ break;
+ sz--;