123384Smckusick /* 237728Smckusick * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 337728Smckusick * All rights reserved. 423384Smckusick * 544444Sbostic * %sccs.include.redist.c% 637728Smckusick * 7*47974Skarels * @(#)sys_generic.c 7.27 (Berkeley) 04/12/91 823384Smckusick */ 97423Sroot 1017094Sbloom #include "param.h" 1117094Sbloom #include "systm.h" 1245914Smckusick #include "filedesc.h" 1317094Sbloom #include "ioctl.h" 1417094Sbloom #include "file.h" 1517094Sbloom #include "proc.h" 1617094Sbloom #include "uio.h" 1717094Sbloom #include "kernel.h" 1817094Sbloom #include "stat.h" 1931653Smckusick #include "malloc.h" 2037127Skarels #ifdef KTRACE 2137127Skarels #include "ktrace.h" 2237127Skarels #endif 237423Sroot 247423Sroot /* 257423Sroot * Read system call. 267423Sroot */ 2745122Sbostic /* ARGSUSED */ 2842922Smckusick read(p, uap, retval) 2942922Smckusick struct proc *p; 3042922Smckusick register struct args { 317423Sroot int fdes; 327423Sroot char *cbuf; 337423Sroot unsigned count; 3442922Smckusick } *uap; 3542922Smckusick int *retval; 3642922Smckusick { 3737728Smckusick register struct file *fp; 3845914Smckusick register struct filedesc *fdp = p->p_fd; 397746Sroot struct uio auio; 407746Sroot struct iovec aiov; 4137728Smckusick long cnt, error = 0; 4237728Smckusick #ifdef KTRACE 4337728Smckusick struct iovec ktriov; 4437728Smckusick #endif 457423Sroot 4647540Skarels if (((unsigned)uap->fdes) >= fdp->fd_nfiles || 47*47974Skarels (fp = fdp->fd_ofiles[uap->fdes]) == NULL || 4837728Smckusick (fp->f_flag & FREAD) == 0) 4944405Skarels return (EBADF); 507820Sroot aiov.iov_base = (caddr_t)uap->cbuf; 517820Sroot aiov.iov_len = uap->count; 527820Sroot auio.uio_iov = &aiov; 537820Sroot auio.uio_iovcnt = 1; 5437728Smckusick auio.uio_resid = uap->count; 5537728Smckusick auio.uio_rw = UIO_READ; 5637728Smckusick auio.uio_segflg = UIO_USERSPACE; 5737728Smckusick #ifdef KTRACE 5837728Smckusick /* 5937728Smckusick * if tracing, save a copy of iovec 6037728Smckusick */ 6142922Smckusick if (KTRPOINT(p, KTR_GENIO)) 6237728Smckusick ktriov = aiov; 6337728Smckusick #endif 6437728Smckusick cnt = uap->count; 6540703Skarels if (error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred)) 6640703Skarels if (auio.uio_resid != cnt && (error == ERESTART || 6740703Skarels error == EINTR || error == EWOULDBLOCK)) 6840703Skarels error = 0; 6937728Smckusick cnt -= auio.uio_resid; 7037728Smckusick #ifdef KTRACE 7142922Smckusick if (KTRPOINT(p, KTR_GENIO) && error == 0) 7243448Smckusick ktrgenio(p->p_tracep, uap->fdes, UIO_READ, &ktriov, cnt, error); 7337728Smckusick #endif 7442922Smckusick *retval = cnt; 7544405Skarels return (error); 767820Sroot } 777820Sroot 7842922Smckusick /* 7942922Smckusick * Scatter read system call. 8042922Smckusick */ 8145122Sbostic /* ARGSUSED */ 8242922Smckusick readv(p, uap, retval) 8342922Smckusick struct proc *p; 8442922Smckusick register struct args { 857820Sroot int fdes; 867820Sroot struct iovec *iovp; 8726474Skarels unsigned iovcnt; 8842922Smckusick } *uap; 8942922Smckusick int *retval; 9042922Smckusick { 9137728Smckusick register struct file *fp; 9245914Smckusick register struct filedesc *fdp = p->p_fd; 937820Sroot struct uio auio; 9437728Smckusick register struct iovec *iov; 9544939Skarels struct iovec *saveiov; 9637728Smckusick struct iovec aiov[UIO_SMALLIOV]; 9737728Smckusick long i, cnt, error = 0; 9844939Skarels unsigned iovlen; 9937728Smckusick #ifdef KTRACE 10037728Smckusick struct iovec *ktriov = NULL; 10137728Smckusick #endif 1027820Sroot 10347540Skarels if (((unsigned)uap->fdes) >= fdp->fd_nfiles || 104*47974Skarels (fp = fdp->fd_ofiles[uap->fdes]) == NULL || 10537728Smckusick (fp->f_flag & FREAD) == 0) 10644405Skarels return (EBADF); 10744939Skarels /* note: can't use iovlen until iovcnt is validated */ 10844939Skarels iovlen = uap->iovcnt * sizeof (struct iovec); 10937127Skarels if (uap->iovcnt > UIO_SMALLIOV) { 11037728Smckusick if (uap->iovcnt > UIO_MAXIOV) 11144405Skarels return (EINVAL); 11244939Skarels MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); 11344939Skarels saveiov = iov; 11437127Skarels } else 11537127Skarels iov = aiov; 11637127Skarels auio.uio_iov = iov; 1177820Sroot auio.uio_iovcnt = uap->iovcnt; 11837728Smckusick auio.uio_rw = UIO_READ; 11937728Smckusick auio.uio_segflg = UIO_USERSPACE; 12044939Skarels if (error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen)) 12137127Skarels goto done; 12237728Smckusick auio.uio_resid = 0; 12337728Smckusick for (i = 0; i < uap->iovcnt; i++) { 12437728Smckusick if (iov->iov_len < 0) { 12537728Smckusick error = EINVAL; 12637728Smckusick goto done; 12737728Smckusick } 12837728Smckusick auio.uio_resid += iov->iov_len; 12937728Smckusick if (auio.uio_resid < 0) { 13037728Smckusick error = EINVAL; 13137728Smckusick goto done; 13237728Smckusick } 13337728Smckusick iov++; 13437728Smckusick } 13537728Smckusick #ifdef KTRACE 13637728Smckusick /* 13737728Smckusick * if tracing, save a copy of iovec 13837728Smckusick */ 13942922Smckusick if (KTRPOINT(p, KTR_GENIO)) { 14037728Smckusick MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 14137728Smckusick bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 14237728Smckusick } 14337728Smckusick #endif 14437728Smckusick cnt = auio.uio_resid; 14540703Skarels if (error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred)) 14640703Skarels if (auio.uio_resid != cnt && (error == ERESTART || 14740703Skarels error == EINTR || error == EWOULDBLOCK)) 14840703Skarels error = 0; 14937728Smckusick cnt -= auio.uio_resid; 15037728Smckusick #ifdef KTRACE 15137728Smckusick if (ktriov != NULL) { 15241178Smarc if (error == 0) 15343448Smckusick ktrgenio(p->p_tracep, uap->fdes, UIO_READ, ktriov, 15443448Smckusick cnt, error); 15537728Smckusick FREE(ktriov, M_TEMP); 15637728Smckusick } 15737728Smckusick #endif 15842922Smckusick *retval = cnt; 15937127Skarels done: 16037728Smckusick if (uap->iovcnt > UIO_SMALLIOV) 16144939Skarels FREE(saveiov, M_IOV); 16244405Skarels return (error); 1637423Sroot } 1647423Sroot 1657423Sroot /* 1667423Sroot * Write system call 1677423Sroot */ 16842922Smckusick write(p, uap, retval) 16942922Smckusick struct proc *p; 17042922Smckusick register struct args { 1717423Sroot int fdes; 1727423Sroot char *cbuf; 17326474Skarels unsigned count; 17442922Smckusick } *uap; 17542922Smckusick int *retval; 17642922Smckusick { 17737728Smckusick register struct file *fp; 17845914Smckusick register struct filedesc *fdp = p->p_fd; 1797820Sroot struct uio auio; 1807820Sroot struct iovec aiov; 18137728Smckusick long cnt, error = 0; 18237728Smckusick #ifdef KTRACE 18337728Smckusick struct iovec ktriov; 18437728Smckusick #endif 1857423Sroot 18647540Skarels if (((unsigned)uap->fdes) >= fdp->fd_nfiles || 187*47974Skarels (fp = fdp->fd_ofiles[uap->fdes]) == NULL || 18837728Smckusick (fp->f_flag & FWRITE) == 0) 18944405Skarels return (EBADF); 19037728Smckusick aiov.iov_base = (caddr_t)uap->cbuf; 19137728Smckusick aiov.iov_len = uap->count; 1927820Sroot auio.uio_iov = &aiov; 1937820Sroot auio.uio_iovcnt = 1; 19437728Smckusick auio.uio_resid = uap->count; 19537728Smckusick auio.uio_rw = UIO_WRITE; 19637728Smckusick auio.uio_segflg = UIO_USERSPACE; 19737728Smckusick #ifdef KTRACE 19837728Smckusick /* 19937728Smckusick * if tracing, save a copy of iovec 20037728Smckusick */ 20142922Smckusick if (KTRPOINT(p, KTR_GENIO)) 20237728Smckusick ktriov = aiov; 20337728Smckusick #endif 20437728Smckusick cnt = uap->count; 20540703Skarels if (error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred)) { 20640703Skarels if (auio.uio_resid != cnt && (error == ERESTART || 20740703Skarels error == EINTR || error == EWOULDBLOCK)) 20840703Skarels error = 0; 20940703Skarels if (error == EPIPE) 21042922Smckusick psignal(p, SIGPIPE); 21140703Skarels } 21237728Smckusick cnt -= auio.uio_resid; 21337728Smckusick #ifdef KTRACE 21442922Smckusick if (KTRPOINT(p, KTR_GENIO) && error == 0) 21542922Smckusick ktrgenio(p->p_tracep, uap->fdes, UIO_WRITE, 21643448Smckusick &ktriov, cnt, error); 21737728Smckusick #endif 21842922Smckusick *retval = cnt; 21944405Skarels return (error); 2207820Sroot } 2217820Sroot 22242922Smckusick /* 22342922Smckusick * Gather write system call 22442922Smckusick */ 22542922Smckusick writev(p, uap, retval) 22642922Smckusick struct proc *p; 22742922Smckusick register struct args { 2287820Sroot int fdes; 2297820Sroot struct iovec *iovp; 23026474Skarels unsigned iovcnt; 23142922Smckusick } *uap; 23242922Smckusick int *retval; 23342922Smckusick { 23437728Smckusick register struct file *fp; 23545914Smckusick register struct filedesc *fdp = p->p_fd; 2367820Sroot struct uio auio; 23737728Smckusick register struct iovec *iov; 23844939Skarels struct iovec *saveiov; 23937728Smckusick struct iovec aiov[UIO_SMALLIOV]; 24037728Smckusick long i, cnt, error = 0; 24144939Skarels unsigned iovlen; 24237728Smckusick #ifdef KTRACE 24337728Smckusick struct iovec *ktriov = NULL; 24437728Smckusick #endif 2457820Sroot 24647540Skarels if (((unsigned)uap->fdes) >= fdp->fd_nfiles || 247*47974Skarels (fp = fdp->fd_ofiles[uap->fdes]) == NULL || 24837728Smckusick (fp->f_flag & FWRITE) == 0) 24944405Skarels return (EBADF); 25044939Skarels /* note: can't use iovlen until iovcnt is validated */ 25144939Skarels iovlen = uap->iovcnt * sizeof (struct iovec); 25237127Skarels if (uap->iovcnt > UIO_SMALLIOV) { 25337728Smckusick if (uap->iovcnt > UIO_MAXIOV) 25444405Skarels return (EINVAL); 25544939Skarels MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); 25644939Skarels saveiov = iov; 25737127Skarels } else 25837127Skarels iov = aiov; 25937127Skarels auio.uio_iov = iov; 2607820Sroot auio.uio_iovcnt = uap->iovcnt; 26137728Smckusick auio.uio_rw = UIO_WRITE; 26237728Smckusick auio.uio_segflg = UIO_USERSPACE; 26344939Skarels if (error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen)) 26437127Skarels goto done; 26537728Smckusick auio.uio_resid = 0; 26637728Smckusick for (i = 0; i < uap->iovcnt; i++) { 2677820Sroot if (iov->iov_len < 0) { 26837728Smckusick error = EINVAL; 26937728Smckusick goto done; 2707820Sroot } 27137728Smckusick auio.uio_resid += iov->iov_len; 27237728Smckusick if (auio.uio_resid < 0) { 27337728Smckusick error = EINVAL; 27437728Smckusick goto done; 2757820Sroot } 27613270Ssam iov++; 2777820Sroot } 27837127Skarels #ifdef KTRACE 27937728Smckusick /* 28037728Smckusick * if tracing, save a copy of iovec 28137728Smckusick */ 28242922Smckusick if (KTRPOINT(p, KTR_GENIO)) { 28337127Skarels MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 28437728Smckusick bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 28537127Skarels } 28637127Skarels #endif 28737728Smckusick cnt = auio.uio_resid; 28840703Skarels if (error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred)) { 28940703Skarels if (auio.uio_resid != cnt && (error == ERESTART || 29040703Skarels error == EINTR || error == EWOULDBLOCK)) 29140703Skarels error = 0; 29240703Skarels if (error == EPIPE) 29342922Smckusick psignal(p, SIGPIPE); 29440703Skarels } 29537728Smckusick cnt -= auio.uio_resid; 29637127Skarels #ifdef KTRACE 29737127Skarels if (ktriov != NULL) { 29841178Smarc if (error == 0) 29942922Smckusick ktrgenio(p->p_tracep, uap->fdes, UIO_WRITE, 30043448Smckusick ktriov, cnt, error); 30137127Skarels FREE(ktriov, M_TEMP); 30237127Skarels } 30337127Skarels #endif 30442922Smckusick *retval = cnt; 30537728Smckusick done: 30637728Smckusick if (uap->iovcnt > UIO_SMALLIOV) 30744939Skarels FREE(saveiov, M_IOV); 30844405Skarels return (error); 3097423Sroot } 3107423Sroot 3117423Sroot /* 3127423Sroot * Ioctl system call 3137423Sroot */ 31442922Smckusick /* ARGSUSED */ 31542922Smckusick ioctl(p, uap, retval) 31642922Smckusick struct proc *p; 31742922Smckusick register struct args { 3187423Sroot int fdes; 3197423Sroot int cmd; 3207423Sroot caddr_t cmarg; 32142922Smckusick } *uap; 32242922Smckusick int *retval; 32342922Smckusick { 32442922Smckusick register struct file *fp; 32545914Smckusick register struct filedesc *fdp = p->p_fd; 32640703Skarels register int com, error; 3277820Sroot register u_int size; 32831653Smckusick caddr_t memp = 0; 32930530Skarels #define STK_PARAMS 128 33033480Skarels char stkbuf[STK_PARAMS]; 33133480Skarels caddr_t data = stkbuf; 3327423Sroot 33347540Skarels if ((unsigned)uap->fdes >= fdp->fd_nfiles || 334*47974Skarels (fp = fdp->fd_ofiles[uap->fdes]) == NULL) 33544405Skarels return (EBADF); 33640703Skarels if ((fp->f_flag & (FREAD|FWRITE)) == 0) 33744405Skarels return (EBADF); 3387624Ssam com = uap->cmd; 3397624Ssam 3407624Ssam if (com == FIOCLEX) { 341*47974Skarels fdp->fd_ofileflags[uap->fdes] |= UF_EXCLOSE; 34244405Skarels return (0); 3437423Sroot } 3447624Ssam if (com == FIONCLEX) { 345*47974Skarels fdp->fd_ofileflags[uap->fdes] &= ~UF_EXCLOSE; 34644405Skarels return (0); 3477423Sroot } 3487624Ssam 3497624Ssam /* 3507624Ssam * Interpret high order word to find 3517624Ssam * amount of data to be copied to/from the 3527624Ssam * user's address space. 3537624Ssam */ 35430530Skarels size = IOCPARM_LEN(com); 35540703Skarels if (size > IOCPARM_MAX) 35644405Skarels return (ENOTTY); 35733480Skarels if (size > sizeof (stkbuf)) { 35843383Smckusick memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK); 35931653Smckusick data = memp; 36030530Skarels } 36110601Ssam if (com&IOC_IN) { 36210601Ssam if (size) { 36340703Skarels error = copyin(uap->cmarg, data, (u_int)size); 36440703Skarels if (error) { 36531653Smckusick if (memp) 36631653Smckusick free(memp, M_IOCTLOPS); 36744405Skarels return (error); 36831653Smckusick } 36910601Ssam } else 37010601Ssam *(caddr_t *)data = uap->cmarg; 37110601Ssam } else if ((com&IOC_OUT) && size) 37210601Ssam /* 37337127Skarels * Zero the buffer so the user always 37437127Skarels * gets back something deterministic. 37510601Ssam */ 37630530Skarels bzero(data, size); 37711284Ssam else if (com&IOC_VOID) 37811284Ssam *(caddr_t *)data = uap->cmarg; 3797423Sroot 38012751Ssam switch (com) { 3817624Ssam 38212751Ssam case FIONBIO: 38340703Skarels error = fset(fp, FNDELAY, *(int *)data); 38430530Skarels break; 38512751Ssam 38612751Ssam case FIOASYNC: 38740703Skarels error = fset(fp, FASYNC, *(int *)data); 38830530Skarels break; 38912751Ssam 39012751Ssam case FIOSETOWN: 39140703Skarels error = fsetown(fp, *(int *)data); 39230530Skarels break; 39312751Ssam 39412751Ssam case FIOGETOWN: 39540703Skarels error = fgetown(fp, (int *)data); 39630530Skarels break; 39730530Skarels default: 39847540Skarels error = (*fp->f_ops->fo_ioctl)(fp, com, data, p); 39930530Skarels /* 40030530Skarels * Copy any data to user, size was 40130530Skarels * already set and checked above. 40230530Skarels */ 40340703Skarels if (error == 0 && (com&IOC_OUT) && size) 40440703Skarels error = copyout(data, uap->cmarg, (u_int)size); 40530530Skarels break; 4067423Sroot } 40731653Smckusick if (memp) 40831653Smckusick free(memp, M_IOCTLOPS); 40944405Skarels return (error); 4107423Sroot } 4117423Sroot 41212751Ssam int nselcoll; 41317593Skarels 4147423Sroot /* 41512751Ssam * Select system call. 4167423Sroot */ 41742922Smckusick select(p, uap, retval) 41842922Smckusick register struct proc *p; 41942922Smckusick register struct args { 42012751Ssam int nd; 42123523Skarels fd_set *in, *ou, *ex; 42212751Ssam struct timeval *tv; 42342922Smckusick } *uap; 42442922Smckusick int *retval; 42542922Smckusick { 42623523Skarels fd_set ibits[3], obits[3]; 42712751Ssam struct timeval atv; 42840703Skarels int s, ncoll, ni, error = 0, timo; 42912751Ssam 43026277Skarels bzero((caddr_t)ibits, sizeof(ibits)); 43126277Skarels bzero((caddr_t)obits, sizeof(obits)); 43247540Skarels if (uap->nd > p->p_fd->fd_nfiles) 43347540Skarels uap->nd = p->p_fd->fd_nfiles; /* forgiving; slightly wrong */ 43423523Skarels ni = howmany(uap->nd, NFDBITS); 43512751Ssam 43612751Ssam #define getbits(name, x) \ 43712751Ssam if (uap->name) { \ 43840703Skarels error = copyin((caddr_t)uap->name, (caddr_t)&ibits[x], \ 43926277Skarels (unsigned)(ni * sizeof(fd_mask))); \ 44040703Skarels if (error) \ 44112751Ssam goto done; \ 44217593Skarels } 44312751Ssam getbits(in, 0); 44412751Ssam getbits(ou, 1); 44512751Ssam getbits(ex, 2); 44612751Ssam #undef getbits 44712751Ssam 44812751Ssam if (uap->tv) { 44940703Skarels error = copyin((caddr_t)uap->tv, (caddr_t)&atv, 45012751Ssam sizeof (atv)); 45140703Skarels if (error) 45212751Ssam goto done; 45312751Ssam if (itimerfix(&atv)) { 45440703Skarels error = EINVAL; 45512751Ssam goto done; 45612751Ssam } 45717934Skarels s = splhigh(); timevaladd(&atv, &time); splx(s); 45840703Skarels timo = hzto(&atv); 45940703Skarels } else 46040703Skarels timo = 0; 46112751Ssam retry: 46212751Ssam ncoll = nselcoll; 46342922Smckusick p->p_flag |= SSEL; 46447540Skarels error = selscan(p, ibits, obits, uap->nd, retval); 46542922Smckusick if (error || *retval) 46612751Ssam goto done; 46717934Skarels s = splhigh(); 46812971Ssam /* this should be timercmp(&time, &atv, >=) */ 46912971Ssam if (uap->tv && (time.tv_sec > atv.tv_sec || 47012971Ssam time.tv_sec == atv.tv_sec && time.tv_usec >= atv.tv_usec)) { 47112751Ssam splx(s); 47212751Ssam goto done; 47312751Ssam } 47442922Smckusick if ((p->p_flag & SSEL) == 0 || nselcoll != ncoll) { 47512751Ssam splx(s); 47612751Ssam goto retry; 47712751Ssam } 47842922Smckusick p->p_flag &= ~SSEL; 47940703Skarels error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo); 48012751Ssam splx(s); 48140703Skarels if (error == 0) 48240703Skarels goto retry; 48312751Ssam done: 48442922Smckusick p->p_flag &= ~SSEL; 48540703Skarels /* select is not restarted after signals... */ 48640703Skarels if (error == ERESTART) 48740703Skarels error = EINTR; 48840703Skarels if (error == EWOULDBLOCK) 48940703Skarels error = 0; 49012751Ssam #define putbits(name, x) \ 49112751Ssam if (uap->name) { \ 49240703Skarels int error2 = copyout((caddr_t)&obits[x], (caddr_t)uap->name, \ 49326277Skarels (unsigned)(ni * sizeof(fd_mask))); \ 49440703Skarels if (error2) \ 49540703Skarels error = error2; \ 49612751Ssam } 49740703Skarels if (error == 0) { 49821106Skarels putbits(in, 0); 49921106Skarels putbits(ou, 1); 50021106Skarels putbits(ex, 2); 50112751Ssam #undef putbits 50221106Skarels } 50344405Skarels return (error); 50412751Ssam } 50512751Ssam 50647540Skarels selscan(p, ibits, obits, nfd, retval) 50747540Skarels struct proc *p; 50823523Skarels fd_set *ibits, *obits; 50942922Smckusick int nfd, *retval; 51012751Ssam { 51147540Skarels register struct filedesc *fdp = p->p_fd; 51223523Skarels register int which, i, j; 51323523Skarels register fd_mask bits; 51412751Ssam int flag; 51512751Ssam struct file *fp; 51642922Smckusick int error = 0, n = 0; 51712751Ssam 51812751Ssam for (which = 0; which < 3; which++) { 51912751Ssam switch (which) { 52012751Ssam 52112751Ssam case 0: 52212751Ssam flag = FREAD; break; 52312751Ssam 52412751Ssam case 1: 52512751Ssam flag = FWRITE; break; 52612751Ssam 52712751Ssam case 2: 52812751Ssam flag = 0; break; 52912751Ssam } 53023523Skarels for (i = 0; i < nfd; i += NFDBITS) { 53123523Skarels bits = ibits[which].fds_bits[i/NFDBITS]; 53217593Skarels while ((j = ffs(bits)) && i + --j < nfd) { 53317593Skarels bits &= ~(1 << j); 534*47974Skarels fp = fdp->fd_ofiles[i + j]; 53517593Skarels if (fp == NULL) { 53642922Smckusick error = EBADF; 53717593Skarels break; 53817593Skarels } 53947540Skarels if ((*fp->f_ops->fo_select)(fp, flag, p)) { 54023523Skarels FD_SET(i + j, &obits[which]); 54117593Skarels n++; 54217593Skarels } 54312751Ssam } 54412751Ssam } 54512751Ssam } 54642922Smckusick *retval = n; 54742922Smckusick return (error); 54812751Ssam } 54912751Ssam 5507423Sroot /*ARGSUSED*/ 551*47974Skarels #ifdef __STDC__ 552*47974Skarels seltrue(dev_t dev, int which, struct proc *p) 553*47974Skarels #else 55447540Skarels seltrue(dev, flag, p) 55512751Ssam dev_t dev; 55612751Ssam int flag; 55747540Skarels struct proc *p; 558*47974Skarels #endif 5597423Sroot { 5607423Sroot 56112751Ssam return (1); 5627423Sroot } 5638103Sroot 56412751Ssam selwakeup(p, coll) 56512751Ssam register struct proc *p; 56612751Ssam int coll; 5678103Sroot { 5688103Sroot 56912751Ssam if (coll) { 57012751Ssam nselcoll++; 57112751Ssam wakeup((caddr_t)&selwait); 57212751Ssam } 57312751Ssam if (p) { 57417934Skarels int s = splhigh(); 57517270Skarels if (p->p_wchan == (caddr_t)&selwait) { 57617270Skarels if (p->p_stat == SSLEEP) 57717270Skarels setrun(p); 57817270Skarels else 57917270Skarels unsleep(p); 58017270Skarels } else if (p->p_flag & SSEL) 58112751Ssam p->p_flag &= ~SSEL; 58212751Ssam splx(s); 58312751Ssam } 5848103Sroot } 585