int ncp_sock_recv(struct socket *so, struct sockbuf *sio) { int error, flags; sbinit(sio, 1000000); /* limit data returned (inexact, hint only) */ flags = MSG_DONTWAIT; error = so_pru_soreceive(so, NULL, NULL, sio, NULL, &flags); #ifdef NCP_SOCKET_DEBUG if (error) kprintf("ncp_recv: err=%d\n", error); #endif return (error); }
/* The format of the BHS is: Byte/ 0 | 1 | 2 | 3 | / | | | | |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| +---------------+---------------+---------------+---------------+ 0|.|I| Opcode |F| Opcode-specific fields | +---------------+---------------+---------------+---------------+ 4|TotalAHSLength | DataSegmentLength | +---------------+---------------+---------------+---------------+ 8| LUN or Opcode-specific fields | + + 12| | +---------------+---------------+---------------+---------------+ 16| Initiator Task Tag | +---------------+---------------+---------------+---------------+ 20/ Opcode-specific fields / +/ / +---------------+---------------+---------------+---------------+ 48 */ static __inline int so_getbhs(isc_session_t *sp) { bhs_t *bhs = &sp->bhs; struct uio *uio = &sp->uio; struct iovec *iov = &sp->iov; int error, flags; debug_called(8); iov->iov_base = bhs; iov->iov_len = sizeof(bhs_t); uio->uio_iov = iov; uio->uio_iovcnt = 1; uio->uio_rw = UIO_READ; uio->uio_segflg = UIO_SYSSPACE; uio->uio_td = curthread; // why ... uio->uio_resid = sizeof(bhs_t); flags = MSG_WAITALL; error = so_pru_soreceive(sp->soc, NULL, uio, NULL, NULL, &flags); if(error) debug(2, "error=%d so_error=%d uio->uio_resid=%zd iov.iov_len=%zd", error, sp->soc->so_error, uio->uio_resid, iov->iov_len); if(!error && (uio->uio_resid > 0)) { error = EPIPE; // was EAGAIN debug(2, "error=%d so_error=%d uio->uio_resid=%zd iov.iov_len=%zd " "so_state=%x", error, sp->soc->so_error, uio->uio_resid, iov->iov_len, sp->soc->so_state); } return error; }
/* * MPSAFE */ int soo_read(struct file *fp, struct uio *uio, struct ucred *cred, int fflags) { struct socket *so; int error; int msgflags; atomic_set_int(&curthread->td_mpflags, TDF_MP_BATCH_DEMARC); so = (struct socket *)fp->f_data; if (fflags & O_FBLOCKING) msgflags = 0; else if (fflags & O_FNONBLOCKING) msgflags = MSG_FNONBLOCKING; else if (fp->f_flag & FNONBLOCK) msgflags = MSG_FNONBLOCKING; else msgflags = 0; error = so_pru_soreceive(so, NULL, uio, NULL, NULL, &msgflags); return (error); }
static void ncp_watchdog(struct ncp_conn *conn) { char *buf; int error, len, flags; struct socket *so; struct sockaddr *sa; struct sockbuf sio; sa = NULL; while (conn->wdg_so) { /* not a loop */ so = conn->wdg_so; sbinit(&sio, 1000000); flags = MSG_DONTWAIT; error = so_pru_soreceive(so, (struct sockaddr**)&sa, NULL, &sio, NULL, &flags); if (error) break; len = sio.sb_cc; NCPSDEBUG("got watch dog %d\n",len); if (len != 2) { m_freem(sio.sb_mb); break; } buf = mtod(sio.sb_mb, char *); if (buf[1] != '?') { m_freem(sio.sb_mb); break; } buf[1] = 'Y'; error = so_pru_sosend(so, sa, NULL, sio.sb_mb, NULL, 0, curthread); NCPSDEBUG("send watch dog %d\n",error); break; } if (sa) kfree(sa, M_SONAME); return; }