int ReadExact(rfbClientPtr cl, char *buf, int len) { int n; fd_set fds; struct timeval tv; int sock = cl->sock; while (len > 0) { do { #if USETLS if (cl->sslctx) n = rfbssl_read(cl, buf, len); else #endif n = read(sock, buf, len); } while (n < 0 && errno == EINTR); if (n > 0) { buf += n; len -= n; } else if (n == 0) { return 0; } else { if (errno != EWOULDBLOCK && errno != EAGAIN) { return n; } #if USETLS if (cl->sslctx) { if (rfbssl_pending(cl)) continue; } #endif FD_ZERO(&fds); FD_SET(sock, &fds); tv.tv_sec = rfbMaxClientWait / 1000; tv.tv_usec = (rfbMaxClientWait % 1000) * 1000; do { n = select(sock + 1, &fds, NULL, NULL, &tv); } while (n < 0 && errno == EINTR); if (n < 0) { rfbLogPerror("ReadExact: select"); return n; } if (n == 0) { errno = ETIMEDOUT; return -1; } } } return 1; }
int rfbReadExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout) { int sock = cl->sock; int n; fd_set fds; struct timeval tv; while (len > 0) { #ifdef LIBVNCSERVER_WITH_WEBSOCKETS if (cl->wsctx) { n = webSocketsDecode(cl, buf, len); } else if (cl->sslctx) { n = rfbssl_read(cl, buf, len); } else { n = read(sock, buf, len); } #else n = read(sock, buf, len); #endif if (n > 0) { buf += n; len -= n; } else if (n == 0) { return 0; } else { #ifdef WIN32 errno = WSAGetLastError(); #endif if (errno == EINTR) continue; #ifdef LIBVNCSERVER_ENOENT_WORKAROUND if (errno != ENOENT) #endif if (errno != EWOULDBLOCK && errno != EAGAIN) { return n; } #ifdef LIBVNCSERVER_WITH_WEBSOCKETS if (cl->sslctx) { if (rfbssl_pending(cl)) continue; } #endif FD_ZERO(&fds); FD_SET(sock, &fds); tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; n = select(sock+1, &fds, NULL, &fds, &tv); if (n < 0) { rfbLogPerror("ReadExact: select"); return n; } if (n == 0) { rfbErr("ReadExact: select timeout\n"); errno = ETIMEDOUT; return -1; } } } #undef DEBUG_READ_EXACT #ifdef DEBUG_READ_EXACT rfbLog("ReadExact %d bytes\n",len); for(n=0;n<len;n++) fprintf(stderr,"%02x ",(unsigned char)buf[n]); fprintf(stderr,"\n"); #endif return 1; }