for sockets is non-blocking.
This allows us to G/C SS_NBIO. Having to keep the two flags in sync
in a mp-safe way is complicated.
This change introduce a behavior change in sosplice(), it can now
always block. However this should not matter much due to the socket
lock being taken beforhand.
ok bluhm@, benno@, visa@
-.\" $OpenBSD: socreate.9,v 1.9 2017/09/01 15:52:03 jmc Exp $
+.\" $OpenBSD: socreate.9,v 1.10 2018/07/30 12:22:14 mpi Exp $
.\"
.\" Copyright (c) 2006 Robert N. M. Watson
.\" All rights reserved.
.\"
.\" $FreeBSD: src/share/man/man9/socket.9,v 1.2 2006/12/16 10:32:10 rwatson Exp $
.\"
-.Dd $Mdocdate: September 1 2017 $
+.Dd $Mdocdate: July 30 2018 $
.Dt SOCREATE 9
.Os
.Sh NAME
.Ft int
.Fn sobind "struct socket *so" "struct mbuf *nam" "struct proc *p"
.Ft void
-.Fn soclose "struct socket *so"
+.Fn soclose "struct socket *so" "int flags"
.Ft int
.Fn soconnect "struct socket *so" "struct mbuf *nam"
.Ft int
.Fn soconnect
returns an error.
.Pp
-The
-.Dv MSG_DONTWAIT
-flag is not implemented for
-.Fn sosend .
-.Pp
This manual page does not describe how to register socket upcalls or monitor
a socket for readability/writability without using blocking I/O.
-/* $OpenBSD: subr_log.c,v 1.55 2018/02/19 08:59:52 mpi Exp $ */
+/* $OpenBSD: subr_log.c,v 1.56 2018/07/30 12:22:14 mpi Exp $ */
/* $NetBSD: subr_log.c,v 1.11 1996/03/30 22:24:44 christos Exp $ */
/*
#include <sys/filedesc.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
+#include <sys/fcntl.h>
#ifdef KTRACE
#include <sys/ktrace.h>
len = auio.uio_resid;
if (fp) {
- error = sosend(fp->f_data, NULL, &auio, NULL, NULL, 0);
+ int flags = (fp->f_flag & FNONBLOCK) ? MSG_DONTWAIT : 0;
+ error = sosend(fp->f_data, NULL, &auio, NULL, NULL, flags);
if (error == 0)
len -= auio.uio_resid;
} else if (constty || cn_devvp) {
-/* $OpenBSD: sys_socket.c,v 1.39 2018/07/10 08:58:50 mpi Exp $ */
+/* $OpenBSD: sys_socket.c,v 1.40 2018/07/30 12:22:14 mpi Exp $ */
/* $NetBSD: sys_socket.c,v 1.13 1995/08/12 23:59:09 mycroft Exp $ */
/*
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/stat.h>
+#include <sys/fcntl.h>
#include <net/if.h>
#include <net/route.h>
int
soo_read(struct file *fp, off_t *poff, struct uio *uio, struct ucred *cred)
{
+ struct socket *so = (struct socket *)fp->f_data;
+ int flags = 0;
+
+ if (fp->f_flag & FNONBLOCK)
+ flags |= MSG_DONTWAIT;
- return (soreceive((struct socket *)fp->f_data, (struct mbuf **)NULL,
- uio, (struct mbuf **)NULL, (struct mbuf **)NULL, (int *)NULL,
- (socklen_t)0));
+ return (soreceive(so, NULL, uio, NULL, NULL, &flags, 0));
}
int
soo_write(struct file *fp, off_t *poff, struct uio *uio, struct ucred *cred)
{
+ struct socket *so = (struct socket *)fp->f_data;
+ int flags = 0;
+
+ if (fp->f_flag & FNONBLOCK)
+ flags |= MSG_DONTWAIT;
- return (sosend((struct socket *)fp->f_data, (struct mbuf *)NULL,
- uio, (struct mbuf *)NULL, (struct mbuf *)NULL, 0));
+ return (sosend(so, NULL, uio, NULL, NULL, flags));
}
int
switch (cmd) {
case FIONBIO:
- s = solock(so);
- if (*(int *)data)
- so->so_state |= SS_NBIO;
- else
- so->so_state &= ~SS_NBIO;
- sounlock(so, s);
break;
case FIOASYNC:
int
soo_close(struct file *fp, struct proc *p)
{
- int error = 0;
+ int flags, error = 0;
- if (fp->f_data)
- error = soclose(fp->f_data);
+ if (fp->f_data) {
+ flags = (fp->f_flag & FNONBLOCK) ? MSG_DONTWAIT : 0;
+ error = soclose(fp->f_data, flags);
+ }
fp->f_data = 0;
return (error);
}
-/* $OpenBSD: uipc_socket.c,v 1.225 2018/07/05 14:45:07 visa Exp $ */
+/* $OpenBSD: uipc_socket.c,v 1.226 2018/07/30 12:22:14 mpi Exp $ */
/* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */
/*
* Free socket when disconnect complete.
*/
int
-soclose(struct socket *so)
+soclose(struct socket *so, int flags)
{
struct socket *so2;
int s, error = 0;
}
if (so->so_options & SO_LINGER) {
if ((so->so_state & SS_ISDISCONNECTING) &&
- (so->so_state & SS_NBIO))
+ (flags & MSG_DONTWAIT))
goto drop;
while (so->so_state & SS_ISCONNECTED) {
error = sosleep(so, &so->so_timeo,
if (space < clen ||
(space - clen < resid &&
(atomic || space < so->so_snd.sb_lowat))) {
- if ((so->so_state & SS_NBIO) || (flags & MSG_DONTWAIT))
+ if (flags & MSG_DONTWAIT)
snderr(EWOULDBLOCK);
sbunlock(so, &so->so_snd);
error = sbwait(so, &so->so_snd);
flags = *flagsp &~ MSG_EOR;
else
flags = 0;
- if (so->so_state & SS_NBIO)
- flags |= MSG_DONTWAIT;
if (flags & MSG_OOB) {
m = m_get(M_WAIT, MT_DATA);
s = solock(so);
}
if (uio->uio_resid == 0 && controlp == NULL)
goto release;
- if ((so->so_state & SS_NBIO) || (flags & MSG_DONTWAIT)) {
+ if (flags & MSG_DONTWAIT) {
error = EWOULDBLOCK;
goto release;
}
/* If no fd is given, unsplice by removing existing link. */
if (fd < 0) {
/* Lock receive buffer. */
- if ((error = sblock(so, &so->so_rcv,
- (so->so_state & SS_NBIO) ? M_NOWAIT : M_WAITOK)) != 0) {
+ if ((error = sblock(so, &so->so_rcv, M_WAITOK)) != 0) {
return (error);
}
if (so->so_sp->ssp_socket)
}
/* Lock both receive and send buffer. */
- if ((error = sblock(so, &so->so_rcv,
- (so->so_state & SS_NBIO) ? M_NOWAIT : M_WAITOK)) != 0) {
+ if ((error = sblock(so, &so->so_rcv, M_WAITOK)) != 0) {
goto frele;
}
if ((error = sblock(so, &sosp->so_snd, M_WAITOK)) != 0) {
-/* $OpenBSD: uipc_syscalls.c,v 1.177 2018/06/20 10:52:49 mpi Exp $ */
+/* $OpenBSD: uipc_syscalls.c,v 1.178 2018/07/30 12:22:14 mpi Exp $ */
/* $NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $ */
/*
error = falloc(p, &fp, &fd);
if (error) {
fdpunlock(fdp);
- soclose(so);
+ soclose(so, MSG_DONTWAIT);
} else {
fp->f_flag = fflag;
fp->f_type = DTYPE_SOCKET;
fp->f_ops = &socketops;
- if (nonblock)
- so->so_state |= SS_NBIO;
so->so_state |= ss;
fp->f_data = so;
fdinsert(fdp, fd, cloexec, fp);
error = EINVAL;
goto out;
}
- if ((head->so_state & SS_NBIO) && head->so_qlen == 0) {
+ if ((headfp->f_flag & FNONBLOCK) && head->so_qlen == 0) {
if (head->so_state & SS_CANTRCVMORE)
error = ECONNABORTED;
else
error = copyaddrout(p, nam, name, namelen, anamelen);
out:
if (!error) {
- if (nflag & FNONBLOCK)
- so->so_state |= SS_NBIO;
- else
- so->so_state &= ~SS_NBIO;
sounlock(head, s);
fdplock(fdp);
fp->f_data = so;
error = soconnect(so, nam);
if (error)
goto bad;
- if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
+ if ((fp->f_flag & FNONBLOCK) && (so->so_state & SS_ISCONNECTING)) {
error = EINPROGRESS;
goto out;
}
if (KTRPOINT(p, KTR_STRUCT))
ktrfds(p, sv, 2);
#endif
- if (nonblock) {
- (*fp1->f_ops->fo_ioctl)(fp1, FIONBIO, (caddr_t)&type,
- p);
- (*fp2->f_ops->fo_ioctl)(fp2, FIONBIO, (caddr_t)&type,
- p);
- }
fdinsert(fdp, sv[0], cloexec, fp1);
fdinsert(fdp, sv[1], cloexec, fp2);
fdpunlock(fdp);
KERNEL_UNLOCK();
free2:
if (so2 != NULL)
- (void)soclose(so2);
+ (void)soclose(so2, 0);
free1:
if (so1 != NULL)
- (void)soclose(so1);
+ (void)soclose(so1, 0);
return (error);
}
if ((error = getsock(p, s, &fp)) != 0)
return (error);
so = fp->f_data;
+ if (fp->f_flag & FNONBLOCK)
+ flags |= MSG_DONTWAIT;
error = pledge_sendit(p, mp->msg_name);
if (error)
}
#endif
len = auio.uio_resid;
+ if (fp->f_flag & FNONBLOCK)
+ mp->msg_flags |= MSG_DONTWAIT;
error = soreceive(fp->f_data, &from, &auio, NULL,
mp->msg_control ? &control : NULL,
&mp->msg_flags,
-/* $OpenBSD: fifo_vnops.c,v 1.67 2018/06/06 06:55:22 mpi Exp $ */
+/* $OpenBSD: fifo_vnops.c,v 1.68 2018/07/30 12:22:14 mpi Exp $ */
/* $NetBSD: fifo_vnops.c,v 1.18 1996/03/16 23:52:42 christos Exp $ */
/*
}
fip->fi_readsock = rso;
if ((error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0)) != 0) {
- (void)soclose(rso);
+ (void)soclose(rso, 0);
free(fip, M_VNODE, sizeof *fip);
vp->v_fifoinfo = NULL;
return (error);
}
fip->fi_writesock = wso;
if ((error = soconnect2(wso, rso)) != 0) {
- (void)soclose(wso);
- (void)soclose(rso);
+ (void)soclose(wso, 0);
+ (void)soclose(rso, 0);
free(fip, M_VNODE, sizeof *fip);
vp->v_fifoinfo = NULL;
return (error);
struct vop_read_args *ap = v;
struct uio *uio = ap->a_uio;
struct socket *rso = ap->a_vp->v_fifoinfo->fi_readsock;
- int error;
+ int error, flags = 0;
#ifdef DIAGNOSTIC
if (uio->uio_rw != UIO_READ)
if (uio->uio_resid == 0)
return (0);
if (ap->a_ioflag & IO_NDELAY)
- rso->so_state |= SS_NBIO;
+ flags |= MSG_DONTWAIT;
VOP_UNLOCK(ap->a_vp);
- error = soreceive(rso, NULL, uio, NULL, NULL, NULL, 0);
+ error = soreceive(rso, NULL, uio, NULL, NULL, &flags, 0);
vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
if (ap->a_ioflag & IO_NDELAY) {
- rso->so_state &= ~SS_NBIO;
if (error == EWOULDBLOCK &&
ap->a_vp->v_fifoinfo->fi_writers == 0)
error = 0;
{
struct vop_write_args *ap = v;
struct socket *wso = ap->a_vp->v_fifoinfo->fi_writesock;
- int error;
+ int error, flags = 0;
#ifdef DIAGNOSTIC
if (ap->a_uio->uio_rw != UIO_WRITE)
panic("fifo_write mode");
#endif
- /* XXXSMP changing state w/o lock isn't safe. */
if (ap->a_ioflag & IO_NDELAY)
- wso->so_state |= SS_NBIO;
+ flags |= MSG_DONTWAIT;
VOP_UNLOCK(ap->a_vp);
- error = sosend(wso, NULL, ap->a_uio, NULL, NULL, 0);
+ error = sosend(wso, NULL, ap->a_uio, NULL, NULL, flags);
vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
- if (ap->a_ioflag & IO_NDELAY)
- wso->so_state &= ~SS_NBIO;
return (error);
}
}
}
if (fip->fi_readers == 0 && fip->fi_writers == 0) {
- error1 = soclose(fip->fi_readsock);
- error2 = soclose(fip->fi_writesock);
+ error1 = soclose(fip->fi_readsock, 0);
+ error2 = soclose(fip->fi_writesock, 0);
free(fip, M_VNODE, sizeof *fip);
vp->v_fifoinfo = NULL;
}
if (fip == NULL)
return (0);
- soclose(fip->fi_readsock);
- soclose(fip->fi_writesock);
+ soclose(fip->fi_readsock, 0);
+ soclose(fip->fi_writesock, 0);
free(fip, M_VNODE, sizeof *fip);
vp->v_fifoinfo = NULL;
-/* $OpenBSD: bfd.c,v 1.71 2018/06/06 06:55:22 mpi Exp $ */
+/* $OpenBSD: bfd.c,v 1.72 2018/07/30 12:22:14 mpi Exp $ */
/*
* Copyright (c) 2016-2018 Peter Hessler <phessler@openbsd.org>
if (bfd->bc_so) {
/* remove upcall before calling soclose or it will be called */
bfd->bc_so->so_upcall = NULL;
- soclose(bfd->bc_so);
+ soclose(bfd->bc_so, MSG_DONTWAIT);
}
if (bfd->bc_soecho) {
bfd->bc_soecho->so_upcall = NULL;
- soclose(bfd->bc_soecho);
+ soclose(bfd->bc_soecho, MSG_DONTWAIT);
}
if (bfd->bc_sosend)
- soclose(bfd->bc_sosend);
+ soclose(bfd->bc_sosend, MSG_DONTWAIT);
rtfree(bfd->bc_rt);
bfd->bc_rt = NULL;
close:
m_free(m);
- soclose(so);
+ soclose(so, MSG_DONTWAIT);
return (NULL);
}
close:
m_free(m);
- soclose(so);
+ soclose(so, MSG_DONTWAIT);
return (NULL);
}
-/* $OpenBSD: if_pflow.c,v 1.89 2018/07/16 16:54:30 jasper Exp $ */
+/* $OpenBSD: if_pflow.c,v 1.90 2018/07/30 12:22:14 mpi Exp $ */
/*
* Copyright (c) 2011 Florian Obser <florian@narrans.de>
mq_purge(&sc->sc_outputqueue);
m_freem(sc->send_nam);
if (sc->so != NULL) {
- error = soclose(sc->so);
+ error = soclose(sc->so, MSG_DONTWAIT);
sc->so = NULL;
}
if (sc->sc_flowdst != NULL)
free(sc->sc_flowdst, M_DEVBUF, sc->sc_flowdst->sa_len);
sc->sc_flowdst = NULL;
if (sc->so != NULL) {
- soclose(sc->so);
+ soclose(sc->so, MSG_DONTWAIT);
sc->so = NULL;
}
}
free(sc->sc_flowsrc, M_DEVBUF, sc->sc_flowsrc->sa_len);
sc->sc_flowsrc = NULL;
if (sc->so != NULL) {
- soclose(sc->so);
+ soclose(sc->so, MSG_DONTWAIT);
sc->so = NULL;
}
switch(pflowr->flowsrc.ss_family) {
sounlock(so, s);
m_freem(m);
if (error) {
- soclose(so);
+ soclose(so, MSG_DONTWAIT);
return (error);
}
}
sc->so = so;
}
} else if (!pflowvalidsockaddr(sc->sc_flowdst, 0)) {
- soclose(sc->so);
+ soclose(sc->so, MSG_DONTWAIT);
sc->so = NULL;
}
-/* $OpenBSD: krpc_subr.c,v 1.33 2018/06/06 06:55:22 mpi Exp $ */
+/* $OpenBSD: krpc_subr.c,v 1.34 2018/07/30 12:22:14 mpi Exp $ */
/* $NetBSD: krpc_subr.c,v 1.12.4.1 1996/06/07 00:52:26 cgd Exp $ */
/*
m_freem(nam);
m_freem(mhead);
m_freem(from);
- soclose(so);
+ soclose(so, 0);
return error;
}
-/* $OpenBSD: nfs_boot.c,v 1.44 2017/11/14 16:01:55 tb Exp $ */
+/* $OpenBSD: nfs_boot.c,v 1.45 2018/07/30 12:22:14 mpi Exp $ */
/* $NetBSD: nfs_boot.c,v 1.26 1996/05/07 02:51:25 thorpej Exp $ */
/*
if (error)
panic("nfs_boot: set if addr, error=%d", error);
- soclose(so);
+ soclose(so, 0);
TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
if (ifa->ifa_addr->sa_family == AF_INET)
-/* $OpenBSD: nfs_socket.c,v 1.129 2018/06/06 06:55:22 mpi Exp $ */
+/* $OpenBSD: nfs_socket.c,v 1.130 2018/07/30 12:22:14 mpi Exp $ */
/* $NetBSD: nfs_socket.c,v 1.27 1996/04/15 20:20:00 thorpej Exp $ */
/*
so = nmp->nm_so;
nmp->nm_so = NULL;
soshutdown(so, SHUT_RDWR);
- soclose(so);
+ soclose(so, 0);
}
}
-/* $OpenBSD: socketvar.h,v 1.85 2018/07/10 10:02:14 bluhm Exp $ */
+/* $OpenBSD: socketvar.h,v 1.86 2018/07/30 12:22:14 mpi Exp $ */
/* $NetBSD: socketvar.h,v 1.18 1996/02/09 18:25:38 christos Exp $ */
/*-
#define SS_ISDISCONNECTED 0x800 /* socket disconnected from peer */
#define SS_PRIV 0x080 /* privileged for broadcast, raw... */
-#define SS_NBIO 0x100 /* non-blocking ops */
#define SS_ASYNC 0x200 /* async i/o notify */
#define SS_CONNECTOUT 0x1000 /* connect, not accept, at this end */
#define SS_ISSENDING 0x2000 /* hint for lower layer */
int sobind(struct socket *so, struct mbuf *nam, struct proc *p);
void socantrcvmore(struct socket *so);
void socantsendmore(struct socket *so);
-int soclose(struct socket *so);
+int soclose(struct socket *, int);
int soconnect(struct socket *so, struct mbuf *nam);
int soconnect2(struct socket *so1, struct socket *so2);
int socreate(int dom, struct socket **aso, int type, int proto);