/* * Fill the stream buffer with a record for a non-blocking connection. * Return true if a record is available in the buffer, false if not. */ bool_t __xdrrec_getrec(XDR *xdrs, enum xprt_stat *statp, bool_t expectdata) { RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); ssize_t n; int fraglen; if (!rstrm->in_haveheader) { n = rstrm->readit(rstrm->tcp_handle, rstrm->in_hdrp, (int)sizeof (rstrm->in_header) - rstrm->in_hdrlen); if (n == 0) { *statp = expectdata ? XPRT_DIED : XPRT_IDLE; return FALSE; } if (n < 0) { *statp = XPRT_DIED; return FALSE; } rstrm->in_hdrp += n; rstrm->in_hdrlen += n; if (rstrm->in_hdrlen < sizeof (rstrm->in_header)) { *statp = XPRT_MOREREQS; return FALSE; } rstrm->in_header = ntohl(rstrm->in_header); fraglen = (int)(rstrm->in_header & ~LAST_FRAG); if (fraglen == 0 || fraglen > rstrm->in_maxrec || (rstrm->in_reclen + fraglen) > rstrm->in_maxrec) { *statp = XPRT_DIED; return FALSE; } rstrm->in_reclen += fraglen; if (rstrm->in_reclen > rstrm->recvsize) realloc_stream(rstrm, rstrm->in_reclen); if (rstrm->in_header & LAST_FRAG) { rstrm->in_header &= ~LAST_FRAG; rstrm->last_frag = TRUE; } /* * We can only reasonably expect to read once from a * non-blocking stream. Reading the fragment header * may have drained the stream. */ expectdata = FALSE; } n = rstrm->readit(rstrm->tcp_handle, rstrm->in_base + rstrm->in_received, (rstrm->in_reclen - rstrm->in_received)); if (n < 0) { *statp = XPRT_DIED; return FALSE; } if (n == 0) { *statp = expectdata ? XPRT_DIED : XPRT_IDLE; return FALSE; } rstrm->in_received += n; if (rstrm->in_received == rstrm->in_reclen) { rstrm->in_haveheader = FALSE; rstrm->in_hdrp = (char *)(void *)&rstrm->in_header; rstrm->in_hdrlen = 0; if (rstrm->last_frag) { rstrm->fbtbc = rstrm->in_reclen; rstrm->in_boundry = rstrm->in_base + rstrm->in_reclen; rstrm->in_finger = rstrm->in_base; rstrm->in_reclen = rstrm->in_received = 0; *statp = XPRT_MOREREQS; return TRUE; } } *statp = XPRT_MOREREQS; return FALSE; }
/* * Fill the stream buffer with a record for a non-blocking connection. * Return true if a record is available in the buffer, false if not. */ bool_t __xdrrec_getrec(XDR *xdrs, enum xprt_stat *statp, bool_t expectdata) { RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); ssize_t n; int fraglen; if (!rstrm->in_haveheader) { n = rstrm->readit(rstrm->tcp_handle, rstrm->in_hdrp, (int)sizeof (rstrm->in_header) - rstrm->in_hdrlen); if (n == 0) { *statp = expectdata ? XPRT_DIED : XPRT_IDLE; return FALSE; } if (n < 0) { *statp = XPRT_DIED; return FALSE; } rstrm->in_hdrp += n; _DIAGASSERT(__type_fit(int, n)); rstrm->in_hdrlen += (int)n; if (rstrm->in_hdrlen < (int)sizeof(rstrm->in_header)) { *statp = XPRT_MOREREQS; return FALSE; } rstrm->in_header = ntohl(rstrm->in_header); fraglen = (int)(rstrm->in_header & ~LAST_FRAG); if (fraglen == 0 || fraglen > rstrm->in_maxrec || (rstrm->in_reclen + fraglen) > rstrm->in_maxrec) { *statp = XPRT_DIED; return FALSE; } rstrm->in_reclen += fraglen; if ((u_int)rstrm->in_reclen > rstrm->recvsize) { if (!realloc_stream(rstrm, rstrm->in_reclen)) { *statp = XPRT_DIED; return FALSE; } } if (rstrm->in_header & LAST_FRAG) { rstrm->in_header &= ~LAST_FRAG; rstrm->last_frag = TRUE; } } n = rstrm->readit(rstrm->tcp_handle, rstrm->in_base + rstrm->in_received, (rstrm->in_reclen - rstrm->in_received)); if (n < 0) { *statp = XPRT_DIED; return FALSE; } if (n == 0) { *statp = expectdata ? XPRT_DIED : XPRT_IDLE; return FALSE; } _DIAGASSERT(__type_fit(int, n)); rstrm->in_received += (int)n; if (rstrm->in_received == rstrm->in_reclen) { rstrm->in_haveheader = FALSE; rstrm->in_hdrp = (char *)(void *)&rstrm->in_header; rstrm->in_hdrlen = 0; if (rstrm->last_frag) { rstrm->fbtbc = rstrm->in_reclen; rstrm->in_boundry = rstrm->in_base + rstrm->in_reclen; rstrm->in_finger = rstrm->in_base; rstrm->in_reclen = rstrm->in_received = 0; *statp = XPRT_MOREREQS; return TRUE; } } *statp = XPRT_MOREREQS; return FALSE; }