/** * g_accept: * @fd: accept connection on this socket * @newfd: fd of the accepted connection * @addr: store the address of the client here * * Accept a connection on the given fd, returning the newfd and the * address of the client in a Zorp SockAddr structure. * * Returns: glib style I/O error **/ GIOStatus g_accept(int fd, int *newfd, GSockAddr **addr) { char sabuf[1024]; socklen_t salen = sizeof(sabuf); do { *newfd = accept(fd, (struct sockaddr *) sabuf, &salen); } while (*newfd == -1 && errno == EINTR); if (*newfd != -1) { *addr = g_sockaddr_new((struct sockaddr *) sabuf, salen); } else if (errno == EAGAIN) { return G_IO_STATUS_AGAIN; } else { return G_IO_STATUS_ERROR; } return G_IO_STATUS_NORMAL; }
static gssize log_transport_dgram_socket_read_method(LogTransport *s, gpointer buf, gsize buflen, LogTransportAuxData *aux) { LogTransportSocket *self = (LogTransportSocket *) s; gint rc; struct sockaddr_storage ss; socklen_t salen = sizeof(ss); do { rc = recvfrom(self->super.fd, buf, buflen, 0, (struct sockaddr *) &ss, &salen); } while (rc == -1 && errno == EINTR); if (rc != -1 && salen && aux) log_transport_aux_data_set_peer_addr_ref(aux, g_sockaddr_new((struct sockaddr *) &ss, salen)); if (rc == 0) { /* DGRAM sockets should never return EOF, they just need to be read again */ rc = -1; errno = EAGAIN; } return rc; }
static gssize _unix_socket_read(gint fd, gpointer buf, gsize buflen, LogTransportAuxData *aux) { gint rc; struct msghdr msg; struct iovec iov[1]; gchar ctlbuf[32]; struct sockaddr_storage ss; msg.msg_name = (struct sockaddr *) &ss; msg.msg_namelen = sizeof(ss); msg.msg_iovlen = 1; msg.msg_iov = iov; iov[0].iov_base = buf; iov[0].iov_len = buflen; msg.msg_control = ctlbuf; msg.msg_controllen = sizeof(ctlbuf); do { rc = recvmsg(fd, &msg, 0); } while (rc == -1 && errno == EINTR); if (rc >= 0) { if (msg.msg_namelen && aux) log_transport_aux_data_set_peer_addr_ref(aux, g_sockaddr_new((struct sockaddr *) &ss, msg.msg_namelen)); _feed_aux_from_cmsg(aux, &msg); } return rc; }
static gssize log_transport_dgram_socket_read_method(LogTransport *s, gpointer buf, gsize buflen, GSockAddr **sa) { LogTransportSocket *self = (LogTransportSocket *) s; gint rc; union { #if HAVE_STRUCT_SOCKADDR_STORAGE struct sockaddr_storage __sas; #endif struct sockaddr __sa; } sas; socklen_t salen = sizeof(sas); do { rc = recvfrom(self->super.fd, buf, buflen, 0, (struct sockaddr *) &sas, &salen); } while (rc == -1 && errno == EINTR); if (rc != -1 && salen && sa) (*sa) = g_sockaddr_new((struct sockaddr *) &sas, salen); if (rc == 0) { /* DGRAM sockets should never return EOF, they just need to be read again */ rc = -1; errno = EAGAIN; } return rc; }
static gssize log_transport_plain_read_method(LogTransport *s, gpointer buf, gsize buflen, GSockAddr **sa) { LogTransportPlain *self = (LogTransportPlain *) s; gint rc; if ((self->super.flags & LTF_RECV) == 0) { if (sa) *sa = NULL; do { if (self->super.timeout) alarm_set(self->super.timeout); rc = read(self->super.fd, buf, buflen); if (self->super.timeout > 0 && rc == -1 && errno == EINTR && alarm_has_fired()) { msg_notice("Nonblocking read has blocked, returning with an error", evt_tag_int("fd", self->super.fd), evt_tag_int("timeout", self->super.timeout), NULL); alarm_cancel(); break; } if (self->super.timeout) alarm_cancel(); } while (rc == -1 && errno == EINTR); } else { union { #if HAVE_STRUCT_SOCKADDR_STORAGE struct sockaddr_storage __sas; #endif struct sockaddr __sa; } sas; socklen_t salen = sizeof(sas); do { rc = recvfrom(self->super.fd, buf, buflen, 0, (struct sockaddr *) &sas, &salen); } while (rc == -1 && errno == EINTR); if (rc != -1 && salen && sa) (*sa) = g_sockaddr_new((struct sockaddr *) &sas, salen); } return rc; }