int osi_NetReceive(osi_socket so, struct sockaddr_in *from, struct iovec *iov, int iovcnt, int *lengthp) { struct msghdr msg; int code; #ifdef ADAPT_PMTU int sockerr; int esize; #endif struct iovec tmpvec[RX_MAXWVECS + 2]; struct socket *sop = (struct socket *)so; if (iovcnt > RX_MAXWVECS + 2) { osi_Panic("Too many (%d) iovecs passed to osi_NetReceive\n", iovcnt); } #ifdef ADAPT_PMTU while (1) { sockerr=0; esize = sizeof(sockerr); kernel_getsockopt(sop, SOL_SOCKET, SO_ERROR, (char *)&sockerr, &esize); if (sockerr == 0) break; handle_socket_error(so); } #endif memcpy(tmpvec, iov, iovcnt * sizeof(struct iovec)); msg.msg_name = from; msg.msg_iov = tmpvec; msg.msg_iovlen = iovcnt; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_flags = 0; code = kernel_recvmsg(sop, &msg, (struct kvec *)tmpvec, iovcnt, *lengthp, 0); if (code < 0) { afs_try_to_freeze(); /* Clear the error before using the socket again. * Oh joy, Linux has hidden header files as well. It appears we can * simply call again and have it clear itself via sock_error(). */ flush_signals(current); /* We don't want no stinkin' signals. */ rxk_lastSocketError = code; rxk_nSocketErrors++; } else { *lengthp = code; code = 0; } return code; }
int osi_NetReceive(osi_socket so, struct sockaddr_in *from, struct iovec *iov, int iovcnt, int *lengthp) { struct msghdr msg; int code; struct iovec tmpvec[RX_MAXWVECS + 2]; struct socket *sop = (struct socket *)so; if (iovcnt > RX_MAXWVECS + 2) { osi_Panic("Too many (%d) iovecs passed to osi_NetReceive\n", iovcnt); } memcpy(tmpvec, iov, iovcnt * sizeof(struct iovec)); msg.msg_name = from; #if defined(STRUCT_MSGHDR_HAS_MSG_ITER) msg.msg_iter.iov = tmpvec; msg.msg_iter.nr_segs = iovcnt; #else msg.msg_iov = tmpvec; msg.msg_iovlen = iovcnt; #endif msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_flags = 0; code = kernel_recvmsg(sop, &msg, (struct kvec *)tmpvec, iovcnt, *lengthp, 0); if (code < 0) { afs_try_to_freeze(); /* Clear the error before using the socket again. * Oh joy, Linux has hidden header files as well. It appears we can * simply call again and have it clear itself via sock_error(). */ flush_signals(current); /* We don't want no stinkin' signals. */ rxk_lastSocketError = code; rxk_nSocketErrors++; do_handlesocketerror(so); } else { *lengthp = code; code = 0; } return code; }