ssize_t R_SockRead(int sockp, void *buf, size_t len, int blocking, int timeout) { ssize_t res; if(blocking && R_SocketWait(sockp, 0, timeout) != 0) return 0; res = recv(sockp, buf, len, 0); return (res >= 0) ? res : -socket_errno(); }
ssize_t R_SockRead(int sockp, void *buf, size_t len, int blocking, int timeout) { ssize_t res; if(blocking && (res = R_SocketWait(sockp, 0, timeout)) != 0) return res < 0 ? res : 0; /* socket error or timeout */ res = recv(sockp, buf, len, 0); return (res >= 0) ? res : -socket_errno(); }
int R_SockListen(int sockp, char *buf, int len, int timeout) { check_init(); /* inserting a wait here will eliminate most blocking, but there are scenarios under which the Sock_listen call might block after the wait has completed. LT */ R_SocketWait(sockp, 0, timeout); return Sock_listen(sockp, buf, len, NULL); }
int R_SockListen(int sockp, char *buf, int len, int timeout) { check_init(); /* inserting a wait here will eliminate most blocking, but there are scenarios under which the Sock_listen call might block after the wait has completed. LT */ int res = 0; do { res = R_SocketWait(sockp, 0, timeout); } while (res < 0 && -res == EINTR); if(res != 0) return -1; /* socket error or timeout */ return Sock_listen(sockp, buf, len, NULL); }
ssize_t R_SockWrite(int sockp, const void *buf, size_t len, int timeout) { ssize_t res, out = 0; /* Rprintf("socket %d writing |%s|\n", sockp, buf); */ /* This function is not passed a `blocking' argument so the code here is equivalent to blocking == TRUE; it's not clear non-blocking writes make much sense with the current connection interface since there is no way to tell how much, if anything, has been written. LT */ do { if(R_SocketWait(sockp, 1, timeout) != 0) return out; res = send(sockp, buf, len, 0); if (res < 0 && socket_errno() != EWOULDBLOCK) return -socket_errno(); else { { const char *cbuf = buf; cbuf += res; buf = cbuf; } len -= res; out += res; } } while (/* ! blocking && */len > 0); return out; }