summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/uipc_sockbuf.c4
-rw-r--r--sys/kern/uipc_socket.c18
-rw-r--r--sys/kern/uipc_socket2.c4
-rw-r--r--sys/sys/socketvar.h3
4 files changed, 21 insertions, 8 deletions
diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index e718c62..e885fce 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93
- * $Id: uipc_socket2.c,v 1.42 1998/11/23 00:45:38 truckman Exp $
+ * $Id: uipc_socket2.c,v 1.43 1998/12/07 21:58:29 archie Exp $
*/
#include <sys/param.h>
@@ -136,7 +136,7 @@ soisdisconnected(so)
{
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
- so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE);
+ so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE|SS_ISDISCONNECTED);
wakeup((caddr_t)&so->so_timeo);
sowwakeup(so);
sorwakeup(so);
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 1efa8c5..77a4331 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94
- * $Id: uipc_socket.c,v 1.50 1999/01/20 17:31:54 fenner Exp $
+ * $Id: uipc_socket.c,v 1.51 1999/01/20 17:45:22 fenner Exp $
*/
#include <sys/param.h>
@@ -193,7 +193,12 @@ sofree(so)
TAILQ_REMOVE(&head->so_incomp, so, so_list);
head->so_incqlen--;
} else if (so->so_state & SS_COMP) {
- TAILQ_REMOVE(&head->so_comp, so, so_list);
+ /*
+ * We must not decommission a socket that's
+ * on the accept(2) queue. If we do, then
+ * accept(2) may hang after select(2) indicated
+ * that the listening socket was ready.
+ */
} else {
panic("sofree: not queued");
}
@@ -228,6 +233,7 @@ soclose(so)
}
for (sp = so->so_comp.tqh_first; sp != NULL; sp = sonext) {
sonext = sp->so_list.tqe_next;
+ TAILQ_REMOVE(&so->so_comp, sp, so_list);
(void) soabort(sp);
}
}
@@ -288,7 +294,13 @@ soaccept(so, nam)
if ((so->so_state & SS_NOFDREF) == 0)
panic("soaccept: !NOFDREF");
so->so_state &= ~SS_NOFDREF;
- error = (*so->so_proto->pr_usrreqs->pru_accept)(so, nam);
+ if ((so->so_state & SS_ISDISCONNECTED) == 0)
+ error = (*so->so_proto->pr_usrreqs->pru_accept)(so, nam);
+ else {
+ if (nam)
+ *nam = 0;
+ error = 0;
+ }
splx(s);
return (error);
}
diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c
index e718c62..e885fce 100644
--- a/sys/kern/uipc_socket2.c
+++ b/sys/kern/uipc_socket2.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93
- * $Id: uipc_socket2.c,v 1.42 1998/11/23 00:45:38 truckman Exp $
+ * $Id: uipc_socket2.c,v 1.43 1998/12/07 21:58:29 archie Exp $
*/
#include <sys/param.h>
@@ -136,7 +136,7 @@ soisdisconnected(so)
{
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
- so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE);
+ so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE|SS_ISDISCONNECTED);
wakeup((caddr_t)&so->so_timeo);
sowwakeup(so);
sorwakeup(so);
diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h
index 4f9c07a..41f6e53 100644
--- a/sys/sys/socketvar.h
+++ b/sys/sys/socketvar.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)socketvar.h 8.3 (Berkeley) 2/19/95
- * $Id: socketvar.h,v 1.31 1998/11/11 10:04:13 truckman Exp $
+ * $Id: socketvar.h,v 1.32 1998/11/11 10:56:07 truckman Exp $
*/
#ifndef _SYS_SOCKETVAR_H_
@@ -127,6 +127,7 @@ struct socket {
#define SS_INCOMP 0x0800 /* unaccepted, incomplete connection */
#define SS_COMP 0x1000 /* unaccepted, complete connection */
+#define SS_ISDISCONNECTED 0x2000 /* socket disconnected from peer */
/*
* Externalized form of struct socket used by the sysctl(3) interface.
OpenPOWER on IntegriCloud