diff --git a/src/iperf_sctp.c b/src/iperf_sctp.c index 9a61bba44..f2e4baef0 100644 --- a/src/iperf_sctp.c +++ b/src/iperf_sctp.c @@ -56,7 +56,7 @@ iperf_sctp_recv(struct iperf_stream *sp) #if defined(HAVE_SCTP_H) int r; - r = Nread(sp->socket, sp->buffer, sp->settings->blksize, Psctp); + r = Nread_no_select(sp->socket, sp->buffer, sp->settings->blksize, Psctp); if (r < 0) return r; diff --git a/src/iperf_tcp.c b/src/iperf_tcp.c index dc0feda6d..481c09dc8 100644 --- a/src/iperf_tcp.c +++ b/src/iperf_tcp.c @@ -58,7 +58,7 @@ iperf_tcp_recv(struct iperf_stream *sp) { int r; - r = Nread(sp->socket, sp->buffer, sp->settings->blksize, Ptcp); + r = Nread_no_select(sp->socket, sp->buffer, sp->settings->blksize, Ptcp); if (r < 0) return r; diff --git a/src/iperf_udp.c b/src/iperf_udp.c index 760116b4b..150b8c69e 100644 --- a/src/iperf_udp.c +++ b/src/iperf_udp.c @@ -62,7 +62,7 @@ iperf_udp_recv(struct iperf_stream *sp) double transit = 0, d = 0; struct iperf_time sent_time, arrival_time, temp_time; - r = Nread(sp->socket, sp->buffer, size, Pudp); + r = Nread_no_select(sp->socket, sp->buffer, size, Pudp); /* * If we got an error in the read, or if we didn't read anything diff --git a/src/net.c b/src/net.c index c82caff1b..003ff5757 100644 --- a/src/net.c +++ b/src/net.c @@ -452,6 +452,33 @@ Nread(int fd, char *buf, size_t count, int prot) return count - nleft; } +/********************************************************************/ +/* reads 'count' bytes from a socket - but without using select() */ +/********************************************************************/ +int +Nread_no_select(int fd, char *buf, size_t count, int prot) +{ + register ssize_t r; + register size_t nleft = count; + + while (nleft > 0) { + r = read(fd, buf, nleft); + if (r < 0) { + /* XXX EWOULDBLOCK can't happen without non-blocking sockets */ + if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) + break; + else + return NET_HARDERROR; + } else if (r == 0) + break; + + nleft -= r; + buf += r; + + } + return count - nleft; +} + /* * N W R I T E diff --git a/src/net.h b/src/net.h index f0e1b4f98..859c52cef 100644 --- a/src/net.h +++ b/src/net.h @@ -32,6 +32,7 @@ int create_socket(int domain, int proto, const char *local, const char *bind_dev int netdial(int domain, int proto, const char *local, const char *bind_dev, int local_port, const char *server, int port, int timeout); int netannounce(int domain, int proto, const char *local, const char *bind_dev, int port); int Nread(int fd, char *buf, size_t count, int prot); +int Nread_no_select(int fd, char *buf, size_t count, int prot); int Nwrite(int fd, const char *buf, size_t count, int prot) /* __attribute__((hot)) */; int has_sendfile(void); int Nsendfile(int fromfd, int tofd, const char *buf, size_t count) /* __attribute__((hot)) */;