SCCS-vsn: sys/kern/uipc_syscalls.c 4.29
SCCS-vsn: sys/kern/uipc_mbuf.c 1.37
SCCS-vsn: sys/kern/uipc_pipe.c 4.15
SCCS-vsn: sys/kern/uipc_socket.c 4.51
-/* uipc_mbuf.c 1.36 82/06/20 */
+/* uipc_mbuf.c 1.37 82/10/05 */
#include "../h/param.h"
#include "../h/dir.h"
#include "../h/param.h"
#include "../h/dir.h"
m = m_get(canwait);
if (m == 0)
return (0);
m = m_get(canwait);
if (m == 0)
return (0);
bzero(mtod(m, caddr_t), MLEN);
return (m);
}
bzero(mtod(m, caddr_t), MLEN);
return (m);
}
p = mtod(m, struct mbuf *);
n->m_off = ((int)p - (int)n) + off;
mclrefcnt[mtocl(p)]++;
p = mtod(m, struct mbuf *);
n->m_off = ((int)p - (int)n) + off;
mclrefcnt[mtocl(p)]++;
- } else {
- n->m_off = MMINOFF;
bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t),
(unsigned)n->m_len);
bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t),
(unsigned)n->m_len);
if (len != M_COPYALL)
len -= n->m_len;
off = 0;
if (len != M_COPYALL)
len -= n->m_len;
off = 0;
n = m0;
if (len > MLEN)
goto bad;
n = m0;
if (len > MLEN)
goto bad;
m->m_len = 0;
do {
count = MIN(MLEN - m->m_len, len);
m->m_len = 0;
do {
count = MIN(MLEN - m->m_len, len);
-/* uipc_pipe.c 4.14 82/10/03 */
+/* uipc_pipe.c 4.15 82/10/05 */
#include "../h/param.h"
#include "../h/dir.h"
#include "../h/param.h"
#include "../h/dir.h"
+ case PRU_SENDOOB:
+ case PRU_RCVOOB:
return (EOPNOTSUPP);
default:
return (EOPNOTSUPP);
default:
-/* uipc_socket.c 4.50 82/10/03 */
+/* uipc_socket.c 4.51 82/10/05 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/param.h"
#include "../h/systm.h"
* If must go all at once and not enough room now, then
* inform user that this would block and do nothing.
*/
* If must go all at once and not enough room now, then
* inform user that this would block and do nothing.
*/
+sosend(so, nam, uio, flags)
register struct socket *so;
struct mbuf *nam;
struct uio *uio;
register struct socket *so;
struct mbuf *nam;
struct uio *uio;
{
struct mbuf *top = 0;
register struct mbuf *m, **mp = ⊤
{
struct mbuf *top = 0;
register struct mbuf *m, **mp = ⊤
if (sosendallatonce(so) && uio->uio_resid > so->so_snd.sb_hiwat)
return (EMSGSIZE);
if (sosendallatonce(so) && uio->uio_resid > so->so_snd.sb_hiwat)
return (EMSGSIZE);
-#ifdef notdef
- /* NEED TO PREVENT BUSY WAITING IN SELECT FOR WRITING */
- if ((so->so_snd.sb_flags & SB_LOCK) && (so->so_state & SS_NBIO))
- return (EWOULDBLOCK);
-#endif
restart:
sblock(&so->so_snd);
#define snderr(errno) { error = errno; splx(s); goto release; }
restart:
sblock(&so->so_snd);
#define snderr(errno) { error = errno; splx(s); goto release; }
snderr(EDESTADDRREQ);
}
if (top) {
snderr(EDESTADDRREQ);
}
if (top) {
- error = (*so->so_proto->pr_usrreq)(so, PRU_SEND,
+ error = (*so->so_proto->pr_usrreq)(so,
+ (flags & SOF_OOB) ? PRU_SENDOOB : PRU_SEND,
top, (caddr_t)nam, (struct socketopt *)0);
top = 0;
if (error) {
top, (caddr_t)nam, (struct socketopt *)0);
top = 0;
if (error) {
- 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;
+ if (flags & SOF_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);
while (uio->uio_resid > 0 && space > 0) {
}
splx(s);
while (uio->uio_resid > 0 && space > 0) {
len = CLBYTES;
} else {
nopages:
len = CLBYTES;
} else {
nopages:
len = MIN(MLEN, iov->iov_len);
}
uiomove(mtod(m, caddr_t), len, UIO_WRITE, uio);
m->m_len = len;
*mp = m;
mp = &m->m_next;
len = MIN(MLEN, iov->iov_len);
}
uiomove(mtod(m, caddr_t), len, UIO_WRITE, uio);
m->m_len = len;
*mp = m;
mp = &m->m_next;
- space = sbspace(&so->so_snd);
+ if (flags & SOF_OOB)
+ space -= len;
+ else
+ space = sbspace(&so->so_snd);
-soreceive(so, aname, uio)
+soreceive(so, aname, uio, flags)
register struct socket *so;
struct mbuf **aname;
struct uio *uio;
register struct socket *so;
struct mbuf **aname;
struct uio *uio;
{
register struct iovec *iov;
register struct mbuf *m, *n;
u_int len;
{
register struct iovec *iov;
register struct mbuf *m, *n;
u_int len;
+ int eor, s, error = 0, moff, tomark;
+
+ if (flags & SOF_OOB) {
+ struct mbuf *m = m_get(M_WAIT);
+
+ (*so->so_proto->pr_usrreq)(so, PRU_RCVOOB,
+ m, (struct mbuf *)0, (struct socketopt *)0);
+ len = uio->uio_resid;
+ do {
+ if (len > m->m_len)
+ len = m->m_len;
+ uiomove(mtod(m, caddr_t), (int)len, UIO_READ, uio);
+ m = m_free(m);
+ } while (uio->uio_resid && u.u_error == 0 && m);
+ if (m)
+ (void) m_freem(m);
+ return;
+ }
restart:
sblock(&so->so_rcv);
restart:
sblock(&so->so_rcv);
if (m == 0)
panic("receive");
if (so->so_proto->pr_flags & PR_ADDR) {
if (m == 0)
panic("receive");
if (so->so_proto->pr_flags & PR_ADDR) {
- so->so_rcv.sb_cc -= m->m_len;
- so->so_rcv.sb_mbcnt -= MSIZE;
+ if ((flags & SOF_PREVIEW) == 0) {
+ so->so_rcv.sb_cc -= m->m_len;
+ so->so_rcv.sb_mbcnt -= MSIZE;
+ }
+ if (flags & SOF_PREVIEW)
+ *aname = m_copy(m, 0, m->m_len);
+ else
+ *aname = m;
m = m->m_next;
(*aname)->m_next = 0;
} else
m = m->m_next;
(*aname)->m_next = 0;
} else
+ if (flags & SOF_PREVIEW)
+ m = m->m_next;
+ else
+ m = m_free(m);
if (m == 0)
panic("receive 2");
if (m == 0)
panic("receive 2");
+ moff = 0;
+ tomark = so->so_oobmark;
do {
if (uio->uio_resid <= 0)
break;
len = uio->uio_resid;
so->so_state &= ~SS_RCVATMARK;
do {
if (uio->uio_resid <= 0)
break;
len = uio->uio_resid;
so->so_state &= ~SS_RCVATMARK;
- if (so->so_oobmark && len > so->so_oobmark)
- len = so->so_oobmark;
- if (len > m->m_len)
- len = m->m_len;
+ if (tomark && len > tomark)
+ len = tomark;
+ if (len > m->m_len - moff)
+ len = m->m_len - moff;
- uiomove(mtod(m, caddr_t), (int)len, UIO_READ, uio);
+ uiomove(mtod(m, caddr_t) + moff, (int)len, UIO_READ, uio);
s = splnet();
if (len == m->m_len) {
eor = (int)m->m_act;
s = splnet();
if (len == m->m_len) {
eor = (int)m->m_act;
- sbfree(&so->so_rcv, m);
- so->so_rcv.sb_mb = m->m_next;
- MFREE(m, n);
+ if (flags & SOF_PREVIEW)
+ m = m->m_next;
+ else {
+ sbfree(&so->so_rcv, m);
+ MFREE(m, n);
+ m = n;
+ }
+ moff = 0;
- m->m_off += len;
- m->m_len -= len;
- so->so_rcv.sb_cc -= len;
+ if (flags & SOF_PREVIEW)
+ moff += len;
+ else {
+ m->m_off += len;
+ m->m_len -= len;
+ so->so_rcv.sb_cc -= len;
+ }
+ if ((flags & SOF_PREVIEW) == 0 && so->so_oobmark) {
so->so_oobmark -= len;
if (so->so_oobmark == 0) {
so->so_state |= SS_RCVATMARK;
break;
}
}
so->so_oobmark -= len;
if (so->so_oobmark == 0) {
so->so_state |= SS_RCVATMARK;
break;
}
}
- } while ((m = so->so_rcv.sb_mb) && !eor);
+ if (tomark) {
+ tomark -= len;
+ if (tomark == 0)
+ break;
+ }
+ } while (m && !eor);
+ if (flags & SOF_PREVIEW)
+ goto release;
+ so->so_rcv.sb_mb = m;
if ((so->so_proto->pr_flags & PR_ATOMIC) && eor == 0)
do {
if (m == 0)
if ((so->so_proto->pr_flags & PR_ATOMIC) && eor == 0)
do {
if (m == 0)
case SIOCSENDOOB: {
char oob = *(char *)data;
case SIOCSENDOOB: {
char oob = *(char *)data;
+ struct mbuf *m = m_get(M_DONTWAIT);
if (m == 0) {
u.u_error = ENOBUFS;
return;
}
if (m == 0) {
u.u_error = ENOBUFS;
return;
}
- m->m_off = MMINOFF;
- m->m_len = sizeof (char);
*mtod(m, char *) = oob;
(*so->so_proto->pr_usrreq)(so, PRU_SENDOOB,
m, (struct mbuf *)0, (struct socketopt *)0);
*mtod(m, char *) = oob;
(*so->so_proto->pr_usrreq)(so, PRU_SENDOOB,
m, (struct mbuf *)0, (struct socketopt *)0);
- struct mbuf *m = m_get(M_DONTWAIT);
+ struct mbuf *m = m_get(M_WAIT);
if (m == 0) {
u.u_error = ENOBUFS;
return;
}
if (m == 0) {
u.u_error = ENOBUFS;
return;
}
- m->m_off = MMINOFF; *mtod(m, caddr_t) = 0;
(*so->so_proto->pr_usrreq)(so, PRU_RCVOOB,
m, (struct mbuf *)0, (struct socketopt *)0);
*(char *)data = *mtod(m, char *);
(*so->so_proto->pr_usrreq)(so, PRU_RCVOOB,
m, (struct mbuf *)0, (struct socketopt *)0);
*(char *)data = *mtod(m, char *);
-/* uipc_syscalls.c 4.28 82/10/05 */
+/* uipc_syscalls.c 4.29 82/10/05 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/param.h"
#include "../h/systm.h"
u.u_error = sockopt(&aopt, uap->opt);
if (u.u_error) {
m_freem(nam);
u.u_error = sockopt(&aopt, uap->opt);
if (u.u_error) {
m_freem(nam);
}
u.u_error = sobind(fp->f_socket, nam, &aopt);
m_freem(nam);
}
u.u_error = sobind(fp->f_socket, nam, &aopt);
m_freem(nam);
if (uap->opt)
m_free(dtom(aopt.so_optdata));
}
if (uap->opt)
m_free(dtom(aopt.so_optdata));
}
fp->f_socket = so;
ret:
nam = m_get(M_WAIT);
fp->f_socket = so;
ret:
nam = m_get(M_WAIT);
soaccept(so, nam, &aopt);
if (uap->name) {
if (namelen > nam->m_len)
soaccept(so, nam, &aopt);
if (uap->name) {
if (namelen > nam->m_len)
u.u_error = sockname(&to, uap->to, uap->tolen);
if (u.u_error)
goto bad;
u.u_error = sockname(&to, uap->to, uap->tolen);
if (u.u_error)
goto bad;
- u.u_error = sosend(fp->f_socket, to, &auio);
+ u.u_error = sosend(fp->f_socket, to, &auio, uap->flags);
- u.u_error = sosend(fp->f_socket, (struct mbuf *)0, &auio);
+ u.u_error = sosend(fp->f_socket, (struct mbuf *)0, &auio, uap->flags);
- u.u_error = soreceive(fp->f_socket, &from, &auio);
+ u.u_error = soreceive(fp->f_socket, &from, &auio, uap->flags);
if (u.u_error)
goto bad;
if (from == 0)
if (u.u_error)
goto bad;
if (from == 0)
u.u_error = EFAULT;
return;
}
u.u_error = EFAULT;
return;
}
- u.u_error = soreceive(fp->f_socket, (struct mbuf *)0, &auio);
+ u.u_error = soreceive(fp->f_socket, (struct mbuf *)0, &auio, uap->flags);
u.u_r.r_val1 = uap->len - auio.uio_resid;
}
u.u_r.r_val1 = uap->len - auio.uio_resid;
}
if (namelen > MLEN)
return (EINVAL);
m = m_get(M_WAIT);
if (namelen > MLEN)
return (EINVAL);
m = m_get(M_WAIT);
m->m_len = namelen;
if (copyin(name, mtod(m, caddr_t), namelen)) {
(void) m_free(m);
m->m_len = namelen;
if (copyin(name, mtod(m, caddr_t), namelen)) {
(void) m_free(m);
if (so->so_optlen < 0 || so->so_optlen > MLEN)
return (EINVAL);
m = m_get(M_WAIT);
if (so->so_optlen < 0 || so->so_optlen > MLEN)
return (EINVAL);
m = m_get(M_WAIT);
m->m_len = so->so_optlen;
if (copyin(so->so_optdata, mtod(m, caddr_t), m->m_len)) {
(void) m_free(m);
m->m_len = so->so_optlen;
if (copyin(so->so_optdata, mtod(m, caddr_t), m->m_len)) {
(void) m_free(m);