--- kernel/bsd/kern/sys_generic.c 2018/04/24 18:26:01 1.1 +++ kernel/bsd/kern/sys_generic.c 2018/04/24 18:27:45 1.1.1.2 @@ -62,18 +62,41 @@ * * @(#)sys_generic.c 8.9 (Berkeley) 2/14/95 */ - #include #include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include #include #include #include -#include #include #include #include -#include + #if KTRACE #include #endif @@ -706,6 +729,8 @@ postevent(struct socket *sp, struct sock { int mask; struct eventqelt *evq; + register struct tcpcb *tp; + if (sb) sp = sb->sb_so; if (!sp || sp->so_evlist.tqh_first == NULL) return; @@ -747,11 +772,31 @@ postevent(struct socket *sp, struct sock } if (event & EV_RWBYTES) { if ((evq->ee_eventmask & EV_RE) && soreadable(sp)) { + if ((sp->so_type == SOCK_STREAM) && (sp->so_error == ECONNREFUSED) || + (sp->so_error == ECONNRESET)) { + tp = sototcpcb(sp); + if (tp->t_state == TCPS_CLOSED) { + mask |= EV_RE|EV_RESET; + break; + } + } + if (sp->so_state & SS_CANTRCVMORE) { + mask |= EV_RE|EV_FIN; + break; + } mask |= EV_RE; evq->ee_req.er_rcnt = sp->so_rcv.sb_cc; } if ((evq->ee_eventmask & EV_WR) && sowriteable(sp)) { + if ((sp->so_type == SOCK_STREAM) &&(sp->so_error == ECONNREFUSED) || + (sp->so_error == ECONNRESET)) { + tp = sototcpcb(sp); + if (tp->t_state == TCPS_CLOSED) { + mask |= EV_WR|EV_RESET; + break; + } + } mask |= EV_WR; evq->ee_req.er_wcnt = sbspace(&sp->so_snd); } @@ -784,16 +829,19 @@ postevent(struct socket *sp, struct sock } case EV_FIN: - if (evq->ee_eventmask & EV_EX) { - mask |= EV_EX|EV_FIN; + if (evq->ee_eventmask & EV_RE) { + mask |= EV_RE|EV_FIN; break; } case EV_RESET: - if (evq->ee_eventmask & EV_EX) { - mask |= EV_EX|EV_RESET; - break; + if (evq->ee_eventmask & EV_RE) { + mask |= EV_RE|EV_RESET; + } + if (evq->ee_eventmask & EV_WR) { + mask |= EV_WR|EV_RESET; } + break; default: return; @@ -895,6 +943,7 @@ watchevent(p, uap, retval) sp = (struct socket *)fp->f_data; assert(sp != NULL); + eqp->ee_sp = sp; // only allow one watch per file per proc for (np = sp->so_evlist.tqh_first; np != NULL; np = np->ee_slist.tqe_next) {