- for (;;) {
- struct msghdr msghdr;
- struct iovec iovec;
- struct ucred *ucred = NULL;
- struct timeval *tv = NULL;
- struct cmsghdr *cmsg;
- char *label = NULL;
- size_t label_len = 0;
- union {
- struct cmsghdr cmsghdr;
-
- /* We use NAME_MAX space for the
- * SELinux label here. The kernel
- * currently enforces no limit, but
- * according to suggestions from the
- * SELinux people this will change and
- * it will probably be identical to
- * NAME_MAX. For now we use that, but
- * this should be updated one day when
- * the final limit is known.*/
- uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
- CMSG_SPACE(sizeof(struct timeval)) +
- CMSG_SPACE(sizeof(int)) + /* fd */
- CMSG_SPACE(NAME_MAX)]; /* selinux label */
- } control;
- ssize_t n;
- int v;
- int *fds = NULL;
- unsigned n_fds = 0;
-
- if (ioctl(ev->data.fd, SIOCINQ, &v) < 0) {
- log_error("SIOCINQ failed: %m");
- return -errno;
- }
-
- if (s->buffer_size < (size_t) v) {
- void *b;
- size_t l;
-
- l = MAX(LINE_MAX + (size_t) v, s->buffer_size * 2);
- b = realloc(s->buffer, l+1);
-
- if (!b) {
- log_error("Couldn't increase buffer.");
- return -ENOMEM;
- }
-
- s->buffer_size = l;
- s->buffer = b;
- }
-
- zero(iovec);
- iovec.iov_base = s->buffer;
- iovec.iov_len = s->buffer_size;
-
- zero(control);
- zero(msghdr);
- msghdr.msg_iov = &iovec;
- msghdr.msg_iovlen = 1;
- msghdr.msg_control = &control;
- msghdr.msg_controllen = sizeof(control);
-
- n = recvmsg(ev->data.fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
- if (n < 0) {
-
- if (errno == EINTR || errno == EAGAIN)
- return 1;
-
- log_error("recvmsg() failed: %m");
- return -errno;
- }
-
- for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) {
-
- if (cmsg->cmsg_level == SOL_SOCKET &&
- cmsg->cmsg_type == SCM_CREDENTIALS &&
- cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred)))
- ucred = (struct ucred*) CMSG_DATA(cmsg);
- else if (cmsg->cmsg_level == SOL_SOCKET &&
- cmsg->cmsg_type == SCM_SECURITY) {
- label = (char*) CMSG_DATA(cmsg);
- label_len = cmsg->cmsg_len - CMSG_LEN(0);
- } else if (cmsg->cmsg_level == SOL_SOCKET &&
- cmsg->cmsg_type == SO_TIMESTAMP &&
- cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
- tv = (struct timeval*) CMSG_DATA(cmsg);
- else if (cmsg->cmsg_level == SOL_SOCKET &&
- cmsg->cmsg_type == SCM_RIGHTS) {
- fds = (int*) CMSG_DATA(cmsg);
- n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
- }
- }
-
- if (ev->data.fd == s->syslog_fd) {
- char *e;