JSS_throwMsg(env, SOCKET_EXCEPTION,
JSS_throwMsgPrErr(env, SOCKET_EXCEPTION,
Java_org_mozilla_jss_ssl_SSLSocket_socketRead(JNIEnv *env, jobject self,     jbyteArray bufBA, jint off, jint len, jint timeout){    JSSL_SocketData *sock;    jbyte *buf = NULL;    jint size;    PRIntervalTime ivtimeout;    jint nread;    /* get the socket */    if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) {        goto finish;    }    size = (*env)->GetArrayLength(env, bufBA);    if( off < 0 || len < 0 || (off+len) > size) {        JSS_throw(env, INDEX_OUT_OF_BOUNDS_EXCEPTION);        goto finish;    }    buf = (*env)->GetByteArrayElements(env, bufBA, NULL);    if( buf == NULL ) {        goto finish;    }    ivtimeout = (timeout > 0) ? PR_MillisecondsToInterval(timeout)                              : PR_INTERVAL_NO_TIMEOUT;    for(;;) {        nread = PR_Recv(sock->fd, buf+off, len, 0 /*flags*/, ivtimeout);        if( nread >= 0 ) {            /* either we read some bytes, or we hit EOF. Either way, we're               done */            break;        } else {            /* some error, but is it recoverable? */            PRErrorCode err = PR_GetError();            if( err == PR_PENDING_INTERRUPT_ERROR ||                err == PR_IO_PENDING_ERROR )            {                /* just try again */            } else {                /* unrecoverable error */                JSS_throwMsg(env, SOCKET_EXCEPTION,                    "Error reading from socket");                goto finish;            }        }    }    if( nread == 0 ) {        /* EOF in Java is -1 */        nread = -1;    }finish:    (*env)->ReleaseByteArrayElements(env, bufBA, buf,        (nread>0) ? JNI_COMMIT : JNI_ABORT);    return nread;}