diff options
-rw-r--r-- | sys/kern/uipc_sockbuf.c | 4 | ||||
-rw-r--r-- | sys/kern/uipc_socket.c | 18 | ||||
-rw-r--r-- | sys/kern/uipc_socket2.c | 4 | ||||
-rw-r--r-- | sys/sys/socketvar.h | 3 |
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. |