-select()
-{
- register struct uap {
- int nd;
- long *in;
- long *ou;
- long *ex;
- struct timeval *tv;
- } *uap = (struct uap *)u.u_ap;
- int ibits[3], obits[3];
- struct timeval atv;
- int s, tsel, ncoll, rem;
- label_t lqsave;
-
- if (uap->nd >= NOFILE) {
- u.u_error = EINVAL;
- return;
- }
-
-#define getbits(name, x) \
- if (uap->name) { \
- if (copyin((caddr_t)uap->name, (caddr_t)&ibits[x], \
- sizeof (ibits[x]))) { \
- u.u_error = EFAULT; \
- return; \
- } \
- } else \
- ibits[x] = 0;
- getbits(in, 0);
- getbits(ou, 1);
- getbits(ex, 2);
-#undef getbits
-
- if (uap->tv) {
- if (copyin((caddr_t)uap->tv, (caddr_t)&atv, sizeof (atv))) {
- u.u_error = EFAULT;
- return;
- }
- if (itimerfix(&atv)) {
- u.u_error = EINVAL;
- return;
- }
- s = spl7(); timevaladd(&atv, &time); splx(s);
- }
-retry:
- ncoll = nselcoll;
- u.u_procp->p_flag |= SSEL;
- u.u_r.r_val1 = selscan(ibits, obits);
- if (u.u_error)
- return;
- if (u.u_r.r_val1)
- goto done;
- s = spl6();
- if (uap->tv && timercmp(&time, &atv, >=)) {
- splx(s);
- goto done;
- }
- 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;
- if (uap->tv) {
- lqsave = u.u_qsave;
- if (setjmp(&u.u_qsave)) {
- untimeout(unselect, u.u_procp);
- u.u_error = EINTR;
- splx(s);
- return;
- }
- timeout(unselect, u.u_procp, hzto(&atv));
- }
- sleep((caddr_t)&selwait, PZERO+1);
- if (uap->tv) {
- u.u_qsave = lqsave;
- untimeout(unselect, u.u_procp);
- }
- splx(s);
- goto retry;
-done:
-#define putbits(name, x) \
- if (uap->name) { \
- if (copyout((caddr_t)obits[x], (caddr_t)uap->name, \
- sizeof (obits[x]))) { \
- u.u_error = EFAULT; \
- return; \
- } \
- }
- putbits(in, 0);
- putbits(ou, 1);
- putbits(ex, 2);
-#undef putbits
-}
-
-unselect(p)
- register struct proc *p;