+ if (so->so_pcb == 0)
+ goto discard;
+ if (exiting)
+ so->so_options |= SO_KEEPALIVE;
+ if (so->so_state & SS_ISCONNECTED) {
+ if ((so->so_state & SS_ISDISCONNECTING) == 0) {
+ u.u_error = sodisconnect(so, (struct sockaddr *)0);
+ if (u.u_error) {
+ if (exiting)
+ goto drop;
+ splx(s);
+ return;
+ }
+ }
+ if ((so->so_options & SO_DONTLINGER) == 0) {
+ if ((so->so_state & SS_ISDISCONNECTING) &&
+ (so->so_state & SS_NBIO) &&
+ exiting == 0) {
+ u.u_error = EINPROGRESS;
+ splx(s);
+ return;
+ }
+ /* should use tsleep here, for at most linger */
+ while (so->so_state & SS_ISCONNECTED)
+ sleep((caddr_t)&so->so_timeo, PZERO+1);
+ }