/* * Recvmsg */ int rxi_Recvmsg(osi_socket socket, struct msghdr *msg_p, int flags) { #if defined(HAVE_LINUX_ERRQUEUE_H) && defined(ADAPT_PMTU) while((rxi_HandleSocketError(socket)) > 0) ; #endif return recvmsg(socket, msg_p, flags); }
/* * Simulate a blocking sendmsg on the non-blocking socket. * It's non blocking because it was set that way for recvmsg. */ int rxi_Sendmsg(osi_socket socket, struct msghdr *msg_p, int flags) { fd_set *sfds = (fd_set *) 0; while (sendmsg(socket, msg_p, flags) == -1) { int err; rx_stats.sendSelects++; if (!sfds) { if (!(sfds = IOMGR_AllocFDSet())) { (osi_Msg "rx failed to alloc fd_set: "); perror("rx_sendmsg"); return -1; } FD_SET(socket, sfds); } #if defined(HAVE_LINUX_ERRQUEUE_H) && defined(ADAPT_PMTU) while((rxi_HandleSocketError(socket)) > 0) ; #endif #ifdef AFS_NT40_ENV if (WSAGetLastError()) #elif defined(AFS_LINUX22_ENV) /* linux unfortunately returns ECONNREFUSED if the target port * is no longer in use */ /* and EAGAIN if a UDP checksum is incorrect */ if (errno != EWOULDBLOCK && errno != ENOBUFS && errno != ECONNREFUSED && errno != EAGAIN) #else if (errno != EWOULDBLOCK && errno != ENOBUFS) #endif { (osi_Msg "rx failed to send packet: "); perror("rx_sendmsg"); #ifndef AFS_NT40_ENV if (errno > 0) return -errno; #else if (WSAGetLastError() > 0) return -WSAGetLastError(); #endif return -1; } while ((err = select(socket + 1, 0, sfds, 0, 0)) != 1) { if (err >= 0 || errno != EINTR) osi_Panic("rxi_sendmsg: select error %d.%d", err, errno); } } if (sfds) IOMGR_FreeFDSet(sfds); return 0; }