Beispiel #1
0
int
rfbWriteExact(rfbClientPtr cl,
              const char *buf,
              int len)
{
    int sock = cl->sock;
    int n;
    fd_set fds;
    struct timeval tv;
    int totalTimeWaited = 0;
    const int timeout = (cl->screen && cl->screen->maxClientWait) ? cl->screen->maxClientWait : rfbMaxClientWait;

#undef DEBUG_WRITE_EXACT
#ifdef DEBUG_WRITE_EXACT
    rfbLog("WriteExact %d bytes\n",len);
    for(n=0;n<len;n++)
	    fprintf(stderr,"%02x ",(unsigned char)buf[n]);
    fprintf(stderr,"\n");
#endif

#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
    if (cl->wsctx) {
        char *tmp = NULL;
        if ((len = webSocketsEncode(cl, buf, len, &tmp)) < 0) {
            rfbErr("WriteExact: WebSockets encode error\n");
            return -1;
        }
        buf = tmp;
    }
#endif

    LOCK(cl->outputMutex);
    while (len > 0) {
#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
        if (cl->sslctx)
	    n = rfbssl_write(cl, buf, len);
	else
#endif
	    n = write(sock, buf, len);

        if (n > 0) {

            buf += n;
            len -= n;

        } else if (n == 0) {

            rfbErr("WriteExact: write returned 0?\n");
            return 0;

        } else {
#ifdef WIN32
			errno = WSAGetLastError();
#endif
	    if (errno == EINTR)
		continue;

            if (errno != EWOULDBLOCK && errno != EAGAIN) {
	        UNLOCK(cl->outputMutex);
                return n;
            }

            /* Retry every 5 seconds until we exceed timeout.  We
               need to do this because select doesn't necessarily return
               immediately when the other end has gone away */

            FD_ZERO(&fds);
            FD_SET(sock, &fds);
            tv.tv_sec = 5;
            tv.tv_usec = 0;
            n = select(sock+1, NULL, &fds, NULL /* &fds */, &tv);
	    if (n < 0) {
#ifdef WIN32
                errno=WSAGetLastError();
#endif
       	        if(errno==EINTR)
		    continue;
                rfbLogPerror("WriteExact: select");
                UNLOCK(cl->outputMutex);
                return n;
            }
            if (n == 0) {
                totalTimeWaited += 5000;
                if (totalTimeWaited >= timeout) {
                    errno = ETIMEDOUT;
                    UNLOCK(cl->outputMutex);
                    return -1;
                }
            } else {
                totalTimeWaited = 0;
            }
        }
    }
    UNLOCK(cl->outputMutex);
    return 1;
}
Beispiel #2
0
int
WriteExact(rfbClientPtr cl, char *buf, int len)
{
    int n, bytesWritten = 0;
    fd_set fds;
    struct timeval tv;
    int totalTimeWaited = 0;
    int sock = cl->sock;

    while (len > 0) {
        do {
#if USETLS
            if (cl->sslctx)
                n = rfbssl_write(cl, buf, len);
            else
#endif
            n = write(sock, buf, len);
        } while (n < 0 && errno == EINTR);

        if (n > 0) {

            buf += n;
            len -= n;
            bytesWritten += n;
            sendBytes += n;

        } else if (n == 0) {

            rfbLog("WriteExact: write returned 0?\n");
            exit(1);

        } else {
            if (errno != EWOULDBLOCK && errno != EAGAIN && errno != 0) {
                return n;
            }

            /* Retry every 5 seconds until we exceed rfbMaxClientWait.  We
               need to do this because select doesn't necessarily return
               immediately when the other end has gone away */

            FD_ZERO(&fds);
            FD_SET(sock, &fds);
            tv.tv_sec = 5;
            tv.tv_usec = 0;
            do {
              n = select(sock + 1, NULL, &fds, NULL, &tv);
            } while (n < 0 && errno == EINTR);
            if (n < 0) {
                rfbLogPerror("WriteExact: select");
                return n;
            }
            if (n == 0) {
                totalTimeWaited += 5000;
                if (totalTimeWaited >= rfbMaxClientWait) {
                    errno = ETIMEDOUT;
                    return -1;
                }
            } else {
                totalTimeWaited = 0;
            }
        }
    }

    gettimeofday(&cl->lastWrite, NULL);
    cl->sockOffset += bytesWritten;

    return 1;
}