- if (error) {
- splx(s);
- goto release;
- }
- mp = ⊤
- }
- if (uio->uio_resid == 0) {
- splx(s);
- goto release;
- }
- if (flags & MSG_OOB)
- space = 1024;
- else {
- space = sbspace(&so->so_snd);
- if (space <= 0 ||
- sosendallatonce(so) && space < uio->uio_resid) {
- if (so->so_state & SS_NBIO)
- snderr(EWOULDBLOCK);
- sbunlock(&so->so_snd);
- sbwait(&so->so_snd);
- splx(s);
- goto restart;
- }
- }
- splx(s);
- /*
- * Temporary kludge-- don't want to update so_snd in this loop
- * (will be done when sent), but need to recalculate
- * space on each iteration. For now, copy so_snd into a tmp.
- */
- sendtempbuf = so->so_snd;
- while (uio->uio_resid > 0 && space > 0) {
- register struct iovec *iov = uio->uio_iov;
-
- if (iov->iov_len == 0) {
- uio->uio_iov++;
- uio->uio_iovcnt--;
- if (uio->uio_iovcnt < 0)
- panic("sosend");
- continue;
- }
- MGET(m, M_WAIT, MT_DATA);
- if (m == NULL) {
- error = ENOBUFS; /* SIGPIPE? */
- goto release;
- }
- if (iov->iov_len >= CLBYTES && space >= CLBYTES) {
- register struct mbuf *p;
- MCLGET(p, 1);
- if (p == 0)
- goto nopages;
- m->m_off = (int)p - (int)m;
- len = CLBYTES;
- } else {
-nopages:
- len = MIN(MLEN, iov->iov_len);
- }
- error = uiomove(mtod(m, caddr_t), len, UIO_WRITE, uio);
- m->m_len = len;
- *mp = m;