- register struct uap {
- int nfd;
- fd_set *rp, *wp;
- struct timeval *tv;
- } *uap = (struct uap *)u.u_ap;
- fd_set rd, wr;
- int nfds = 0, readable = 0, writeable = 0;
- struct timeval atv, origin, now;
- int s, tsel, ncoll, rem;
-
- if (uap->nfd > NOFILE)
- uap->nfd = NOFILE;
- if (uap->nfd < 0) {
- u.u_error = EBADF;
- return;
- }
- if (uap->tv) {
- if (copyin((caddr_t)uap->tv, (caddr_t)&atv, sizeof (atv))) {
- u.u_error = EFAULT;
- return;
- }
- } else
- timerclear(&atv);
- if (uap->rp && copyin((caddr_t)uap->rp,(caddr_t)&rd,sizeof(fd_set)))
- return;
- if (uap->wp && copyin((caddr_t)uap->wp,(caddr_t)&wr,sizeof(fd_set)))
- return;
-retry:
- s = spl7(); now = time; splx(s);
- ncoll = nselcoll;
- u.u_procp->p_flag |= SSEL;
- if (uap->rp)
- readable = selscan(uap->nfd, rd, &nfds, FREAD);
- if (uap->wp)
- writeable = selscan(uap->nfd, wr, &nfds, FWRITE);
- if (u.u_error)
- goto done;
- if (readable || writeable)
- goto done;
- if (!timerisset(&atv))
- goto done;
- s = spl6();
- if ((u.u_procp->p_flag & SSEL) == 0 || nselcoll != ncoll) {
- u.u_procp->p_flag &= ~SSEL;
- splx(s);
- goto retry;
- }
- u.u_procp->p_flag &= ~SSEL;
- tsel = tsleep((caddr_t)&selwait, PZERO+1, &atv);
- splx(s);
- switch (tsel) {
-
- case TS_OK:
- now = time;
- timevalsub(&now, &origin);
- timevalsub(&atv, now);
- if (atv.tv_sec < 0 || atv.tv_usec < 0)
- timerclear(&atv);
- goto retry;
-
- case TS_SIG:
- u.u_error = EINTR;
- return;