From de2c74a5bbc7447464fed46fc830b13f8dba72dc Mon Sep 17 00:00:00 2001 From: Mike Karels Date: Tue, 17 Sep 1985 03:52:39 -0800 Subject: [PATCH] allow select on exceptional conditions to notify of urgent data pending; connect on connected datagram socket does disconnect first; error status socket option SCCS-vsn: sys/kern/sys_socket.c 6.6 SCCS-vsn: sys/kern/uipc_socket.c 6.17 --- usr/src/sys/kern/sys_socket.c | 11 ++++++++++- usr/src/sys/kern/uipc_socket.c | 32 ++++++++++++++++++++++++-------- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/usr/src/sys/kern/sys_socket.c b/usr/src/sys/kern/sys_socket.c index e56f4318c2..dbe486c5cd 100644 --- a/usr/src/sys/kern/sys_socket.c +++ b/usr/src/sys/kern/sys_socket.c @@ -3,7 +3,7 @@ * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * - * @(#)sys_socket.c 6.5 (Berkeley) %G% + * @(#)sys_socket.c 6.6 (Berkeley) %G% */ #include "param.h" @@ -115,6 +115,15 @@ soo_select(fp, which) } sbselqueue(&so->so_snd); break; + + case 0: + if (so->so_oobmark || + (so->so_state & SS_RCVATMARK)) { + splx(s); + return (1); + } + sbselqueue(&so->so_rcv); + break; } splx(s); return (0); diff --git a/usr/src/sys/kern/uipc_socket.c b/usr/src/sys/kern/uipc_socket.c index d86401c80c..d45875ccdb 100644 --- a/usr/src/sys/kern/uipc_socket.c +++ b/usr/src/sys/kern/uipc_socket.c @@ -3,7 +3,7 @@ * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * - * @(#)uipc_socket.c 6.16 (Berkeley) %G% + * @(#)uipc_socket.c 6.17 (Berkeley) %G% */ #include "param.h" @@ -218,13 +218,19 @@ soconnect(so, nam) int s = splnet(); int error; - if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) { + /* + * If protocol is connection-based, can only connect once. + * Otherwise, if connected, try to disconnect first. + * This allows user to disconnect by connecting to, e.g., + * a null address. + */ + if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING) && + ((so->so_proto->pr_flags & PR_CONNREQUIRED) || + (error = sodisconnect(so)))) error = EISCONN; - goto bad; - } - error = (*so->so_proto->pr_usrreq)(so, PRU_CONNECT, - (struct mbuf *)0, nam, (struct mbuf *)0); -bad: + else + error = (*so->so_proto->pr_usrreq)(so, PRU_CONNECT, + (struct mbuf *)0, nam, (struct mbuf *)0); splx(s); return (error); } @@ -411,7 +417,7 @@ soreceive(so, aname, uio, flags, rightsp) if (flags & MSG_OOB) { m = m_get(M_WAIT, MT_DATA); error = (*pr->pr_usrreq)(so, PRU_RCVOOB, - m, (struct mbuf *)0, (struct mbuf *)0); + m, (struct mbuf *)(flags & MSG_PEEK), (struct mbuf *)0); if (error) goto bad; do { @@ -713,6 +719,11 @@ sogetopt(so, level, optname, mp) *mtod(m, int *) = so->so_options & optname; break; + case SO_ERROR: + *mtod(m, int *) = so->so_error; + so->so_error = 0; + break; + case SO_SNDBUF: *mtod(m, int *) = so->so_snd.sb_hiwat; break; @@ -755,4 +766,9 @@ sohasoutofband(so) gsignal(-so->so_pgrp, SIGURG); else if (so->so_pgrp > 0 && (p = pfind(so->so_pgrp)) != 0) psignal(p, SIGURG); + if (so->so_rcv.sb_sel) { + selwakeup(so->so_rcv.sb_sel, so->so_rcv.sb_flags & SB_COLL); + so->so_rcv.sb_sel = 0; + so->so_rcv.sb_flags &= ~SB_COLL; + } } -- 2.20.1