예제 #1
0
/*
 * 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);
}
예제 #2
0
/*
 * 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;
}