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*45122Sbostic * @(#)sys_generic.c 7.24 (Berkeley) 08/24/90 823384Smckusick */ 97423Sroot 1017094Sbloom #include "param.h" 1117094Sbloom #include "systm.h" 1244405Skarels #include "user.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 */ 27*45122Sbostic /* 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; 387746Sroot struct uio auio; 397746Sroot struct iovec aiov; 4037728Smckusick long cnt, error = 0; 4137728Smckusick #ifdef KTRACE 4237728Smckusick struct iovec ktriov; 4337728Smckusick #endif 447423Sroot 4537728Smckusick if (((unsigned)uap->fdes) >= NOFILE || 4637728Smckusick (fp = u.u_ofile[uap->fdes]) == NULL || 4737728Smckusick (fp->f_flag & FREAD) == 0) 4844405Skarels return (EBADF); 497820Sroot aiov.iov_base = (caddr_t)uap->cbuf; 507820Sroot aiov.iov_len = uap->count; 517820Sroot auio.uio_iov = &aiov; 527820Sroot auio.uio_iovcnt = 1; 5337728Smckusick auio.uio_resid = uap->count; 5437728Smckusick auio.uio_rw = UIO_READ; 5537728Smckusick auio.uio_segflg = UIO_USERSPACE; 5637728Smckusick #ifdef KTRACE 5737728Smckusick /* 5837728Smckusick * if tracing, save a copy of iovec 5937728Smckusick */ 6042922Smckusick if (KTRPOINT(p, KTR_GENIO)) 6137728Smckusick ktriov = aiov; 6237728Smckusick #endif 6337728Smckusick cnt = uap->count; 6440703Skarels if (error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred)) 6540703Skarels if (auio.uio_resid != cnt && (error == ERESTART || 6640703Skarels error == EINTR || error == EWOULDBLOCK)) 6740703Skarels error = 0; 6837728Smckusick cnt -= auio.uio_resid; 6937728Smckusick #ifdef KTRACE 7042922Smckusick if (KTRPOINT(p, KTR_GENIO) && error == 0) 7143448Smckusick ktrgenio(p->p_tracep, uap->fdes, UIO_READ, &ktriov, cnt, error); 7237728Smckusick #endif 7342922Smckusick *retval = cnt; 7444405Skarels return (error); 757820Sroot } 767820Sroot 7742922Smckusick /* 7842922Smckusick * Scatter read system call. 7942922Smckusick */ 80*45122Sbostic /* ARGSUSED */ 8142922Smckusick readv(p, uap, retval) 8242922Smckusick struct proc *p; 8342922Smckusick register struct args { 847820Sroot int fdes; 857820Sroot struct iovec *iovp; 8626474Skarels unsigned iovcnt; 8742922Smckusick } *uap; 8842922Smckusick int *retval; 8942922Smckusick { 9037728Smckusick register struct file *fp; 917820Sroot struct uio auio; 9237728Smckusick register struct iovec *iov; 9344939Skarels struct iovec *saveiov; 9437728Smckusick struct iovec aiov[UIO_SMALLIOV]; 9537728Smckusick long i, cnt, error = 0; 9644939Skarels unsigned iovlen; 9737728Smckusick #ifdef KTRACE 9837728Smckusick struct iovec *ktriov = NULL; 9937728Smckusick #endif 1007820Sroot 10137728Smckusick if (((unsigned)uap->fdes) >= NOFILE || 10237728Smckusick (fp = u.u_ofile[uap->fdes]) == NULL || 10337728Smckusick (fp->f_flag & FREAD) == 0) 10444405Skarels return (EBADF); 10544939Skarels /* note: can't use iovlen until iovcnt is validated */ 10644939Skarels iovlen = uap->iovcnt * sizeof (struct iovec); 10737127Skarels if (uap->iovcnt > UIO_SMALLIOV) { 10837728Smckusick if (uap->iovcnt > UIO_MAXIOV) 10944405Skarels return (EINVAL); 11044939Skarels MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); 11144939Skarels saveiov = iov; 11237127Skarels } else 11337127Skarels iov = aiov; 11437127Skarels auio.uio_iov = iov; 1157820Sroot auio.uio_iovcnt = uap->iovcnt; 11637728Smckusick auio.uio_rw = UIO_READ; 11737728Smckusick auio.uio_segflg = UIO_USERSPACE; 11844939Skarels if (error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen)) 11937127Skarels goto done; 12037728Smckusick auio.uio_resid = 0; 12137728Smckusick for (i = 0; i < uap->iovcnt; i++) { 12237728Smckusick if (iov->iov_len < 0) { 12337728Smckusick error = EINVAL; 12437728Smckusick goto done; 12537728Smckusick } 12637728Smckusick auio.uio_resid += iov->iov_len; 12737728Smckusick if (auio.uio_resid < 0) { 12837728Smckusick error = EINVAL; 12937728Smckusick goto done; 13037728Smckusick } 13137728Smckusick iov++; 13237728Smckusick } 13337728Smckusick #ifdef KTRACE 13437728Smckusick /* 13537728Smckusick * if tracing, save a copy of iovec 13637728Smckusick */ 13742922Smckusick if (KTRPOINT(p, KTR_GENIO)) { 13837728Smckusick MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 13937728Smckusick bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 14037728Smckusick } 14137728Smckusick #endif 14237728Smckusick cnt = auio.uio_resid; 14340703Skarels if (error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred)) 14440703Skarels if (auio.uio_resid != cnt && (error == ERESTART || 14540703Skarels error == EINTR || error == EWOULDBLOCK)) 14640703Skarels error = 0; 14737728Smckusick cnt -= auio.uio_resid; 14837728Smckusick #ifdef KTRACE 14937728Smckusick if (ktriov != NULL) { 15041178Smarc if (error == 0) 15143448Smckusick ktrgenio(p->p_tracep, uap->fdes, UIO_READ, ktriov, 15243448Smckusick cnt, error); 15337728Smckusick FREE(ktriov, M_TEMP); 15437728Smckusick } 15537728Smckusick #endif 15642922Smckusick *retval = cnt; 15737127Skarels done: 15837728Smckusick if (uap->iovcnt > UIO_SMALLIOV) 15944939Skarels FREE(saveiov, M_IOV); 16044405Skarels return (error); 1617423Sroot } 1627423Sroot 1637423Sroot /* 1647423Sroot * Write system call 1657423Sroot */ 16642922Smckusick write(p, uap, retval) 16742922Smckusick struct proc *p; 16842922Smckusick register struct args { 1697423Sroot int fdes; 1707423Sroot char *cbuf; 17126474Skarels unsigned count; 17242922Smckusick } *uap; 17342922Smckusick int *retval; 17442922Smckusick { 17537728Smckusick register struct file *fp; 1767820Sroot struct uio auio; 1777820Sroot struct iovec aiov; 17837728Smckusick long cnt, error = 0; 17937728Smckusick #ifdef KTRACE 18037728Smckusick struct iovec ktriov; 18137728Smckusick #endif 1827423Sroot 18337728Smckusick if (((unsigned)uap->fdes) >= NOFILE || 18437728Smckusick (fp = u.u_ofile[uap->fdes]) == NULL || 18537728Smckusick (fp->f_flag & FWRITE) == 0) 18644405Skarels return (EBADF); 18737728Smckusick aiov.iov_base = (caddr_t)uap->cbuf; 18837728Smckusick aiov.iov_len = uap->count; 1897820Sroot auio.uio_iov = &aiov; 1907820Sroot auio.uio_iovcnt = 1; 19137728Smckusick auio.uio_resid = uap->count; 19237728Smckusick auio.uio_rw = UIO_WRITE; 19337728Smckusick auio.uio_segflg = UIO_USERSPACE; 19437728Smckusick #ifdef KTRACE 19537728Smckusick /* 19637728Smckusick * if tracing, save a copy of iovec 19737728Smckusick */ 19842922Smckusick if (KTRPOINT(p, KTR_GENIO)) 19937728Smckusick ktriov = aiov; 20037728Smckusick #endif 20137728Smckusick cnt = uap->count; 20240703Skarels if (error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred)) { 20340703Skarels if (auio.uio_resid != cnt && (error == ERESTART || 20440703Skarels error == EINTR || error == EWOULDBLOCK)) 20540703Skarels error = 0; 20640703Skarels if (error == EPIPE) 20742922Smckusick psignal(p, SIGPIPE); 20840703Skarels } 20937728Smckusick cnt -= auio.uio_resid; 21037728Smckusick #ifdef KTRACE 21142922Smckusick if (KTRPOINT(p, KTR_GENIO) && error == 0) 21242922Smckusick ktrgenio(p->p_tracep, uap->fdes, UIO_WRITE, 21343448Smckusick &ktriov, cnt, error); 21437728Smckusick #endif 21542922Smckusick *retval = cnt; 21644405Skarels return (error); 2177820Sroot } 2187820Sroot 21942922Smckusick /* 22042922Smckusick * Gather write system call 22142922Smckusick */ 22242922Smckusick writev(p, uap, retval) 22342922Smckusick struct proc *p; 22442922Smckusick register struct args { 2257820Sroot int fdes; 2267820Sroot struct iovec *iovp; 22726474Skarels unsigned iovcnt; 22842922Smckusick } *uap; 22942922Smckusick int *retval; 23042922Smckusick { 23137728Smckusick register struct file *fp; 2327820Sroot struct uio auio; 23337728Smckusick register struct iovec *iov; 23444939Skarels struct iovec *saveiov; 23537728Smckusick struct iovec aiov[UIO_SMALLIOV]; 23637728Smckusick long i, cnt, error = 0; 23744939Skarels unsigned iovlen; 23837728Smckusick #ifdef KTRACE 23937728Smckusick struct iovec *ktriov = NULL; 24037728Smckusick #endif 2417820Sroot 24237728Smckusick if (((unsigned)uap->fdes) >= NOFILE || 24337728Smckusick (fp = u.u_ofile[uap->fdes]) == NULL || 24437728Smckusick (fp->f_flag & FWRITE) == 0) 24544405Skarels return (EBADF); 24644939Skarels /* note: can't use iovlen until iovcnt is validated */ 24744939Skarels iovlen = uap->iovcnt * sizeof (struct iovec); 24837127Skarels if (uap->iovcnt > UIO_SMALLIOV) { 24937728Smckusick if (uap->iovcnt > UIO_MAXIOV) 25044405Skarels return (EINVAL); 25144939Skarels MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); 25244939Skarels saveiov = iov; 25337127Skarels } else 25437127Skarels iov = aiov; 25537127Skarels auio.uio_iov = iov; 2567820Sroot auio.uio_iovcnt = uap->iovcnt; 25737728Smckusick auio.uio_rw = UIO_WRITE; 25837728Smckusick auio.uio_segflg = UIO_USERSPACE; 25944939Skarels if (error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen)) 26037127Skarels goto done; 26137728Smckusick auio.uio_resid = 0; 26237728Smckusick for (i = 0; i < uap->iovcnt; i++) { 2637820Sroot if (iov->iov_len < 0) { 26437728Smckusick error = EINVAL; 26537728Smckusick goto done; 2667820Sroot } 26737728Smckusick auio.uio_resid += iov->iov_len; 26837728Smckusick if (auio.uio_resid < 0) { 26937728Smckusick error = EINVAL; 27037728Smckusick goto done; 2717820Sroot } 27213270Ssam iov++; 2737820Sroot } 27437127Skarels #ifdef KTRACE 27537728Smckusick /* 27637728Smckusick * if tracing, save a copy of iovec 27737728Smckusick */ 27842922Smckusick if (KTRPOINT(p, KTR_GENIO)) { 27937127Skarels MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 28037728Smckusick bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 28137127Skarels } 28237127Skarels #endif 28337728Smckusick cnt = auio.uio_resid; 28440703Skarels if (error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred)) { 28540703Skarels if (auio.uio_resid != cnt && (error == ERESTART || 28640703Skarels error == EINTR || error == EWOULDBLOCK)) 28740703Skarels error = 0; 28840703Skarels if (error == EPIPE) 28942922Smckusick psignal(p, SIGPIPE); 29040703Skarels } 29137728Smckusick cnt -= auio.uio_resid; 29237127Skarels #ifdef KTRACE 29337127Skarels if (ktriov != NULL) { 29441178Smarc if (error == 0) 29542922Smckusick ktrgenio(p->p_tracep, uap->fdes, UIO_WRITE, 29643448Smckusick ktriov, cnt, error); 29737127Skarels FREE(ktriov, M_TEMP); 29837127Skarels } 29937127Skarels #endif 30042922Smckusick *retval = cnt; 30137728Smckusick done: 30237728Smckusick if (uap->iovcnt > UIO_SMALLIOV) 30344939Skarels FREE(saveiov, M_IOV); 30444405Skarels return (error); 3057423Sroot } 3067423Sroot 3077423Sroot /* 3087423Sroot * Ioctl system call 3097423Sroot */ 31042922Smckusick /* ARGSUSED */ 31142922Smckusick ioctl(p, uap, retval) 31242922Smckusick struct proc *p; 31342922Smckusick register struct args { 3147423Sroot int fdes; 3157423Sroot int cmd; 3167423Sroot caddr_t cmarg; 31742922Smckusick } *uap; 31842922Smckusick int *retval; 31942922Smckusick { 32042922Smckusick register struct file *fp; 32140703Skarels register int com, error; 3227820Sroot register u_int size; 32331653Smckusick caddr_t memp = 0; 32430530Skarels #define STK_PARAMS 128 32533480Skarels char stkbuf[STK_PARAMS]; 32633480Skarels caddr_t data = stkbuf; 3277423Sroot 32837728Smckusick if ((unsigned)uap->fdes >= NOFILE || 32937728Smckusick (fp = u.u_ofile[uap->fdes]) == NULL) 33044405Skarels return (EBADF); 33140703Skarels if ((fp->f_flag & (FREAD|FWRITE)) == 0) 33244405Skarels return (EBADF); 3337624Ssam com = uap->cmd; 3347624Ssam 3357624Ssam if (com == FIOCLEX) { 3369592Ssam u.u_pofile[uap->fdes] |= UF_EXCLOSE; 33744405Skarels return (0); 3387423Sroot } 3397624Ssam if (com == FIONCLEX) { 3409592Ssam u.u_pofile[uap->fdes] &= ~UF_EXCLOSE; 34144405Skarels return (0); 3427423Sroot } 3437624Ssam 3447624Ssam /* 3457624Ssam * Interpret high order word to find 3467624Ssam * amount of data to be copied to/from the 3477624Ssam * user's address space. 3487624Ssam */ 34930530Skarels size = IOCPARM_LEN(com); 35040703Skarels if (size > IOCPARM_MAX) 35144405Skarels return (ENOTTY); 35233480Skarels if (size > sizeof (stkbuf)) { 35343383Smckusick memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK); 35431653Smckusick data = memp; 35530530Skarels } 35610601Ssam if (com&IOC_IN) { 35710601Ssam if (size) { 35840703Skarels error = copyin(uap->cmarg, data, (u_int)size); 35940703Skarels if (error) { 36031653Smckusick if (memp) 36131653Smckusick free(memp, M_IOCTLOPS); 36244405Skarels return (error); 36331653Smckusick } 36410601Ssam } else 36510601Ssam *(caddr_t *)data = uap->cmarg; 36610601Ssam } else if ((com&IOC_OUT) && size) 36710601Ssam /* 36837127Skarels * Zero the buffer so the user always 36937127Skarels * gets back something deterministic. 37010601Ssam */ 37130530Skarels bzero(data, size); 37211284Ssam else if (com&IOC_VOID) 37311284Ssam *(caddr_t *)data = uap->cmarg; 3747423Sroot 37512751Ssam switch (com) { 3767624Ssam 37712751Ssam case FIONBIO: 37840703Skarels error = fset(fp, FNDELAY, *(int *)data); 37930530Skarels break; 38012751Ssam 38112751Ssam case FIOASYNC: 38240703Skarels error = fset(fp, FASYNC, *(int *)data); 38330530Skarels break; 38412751Ssam 38512751Ssam case FIOSETOWN: 38640703Skarels error = fsetown(fp, *(int *)data); 38730530Skarels break; 38812751Ssam 38912751Ssam case FIOGETOWN: 39040703Skarels error = fgetown(fp, (int *)data); 39130530Skarels break; 39230530Skarels default: 39340703Skarels error = (*fp->f_ops->fo_ioctl)(fp, com, data); 39430530Skarels /* 39530530Skarels * Copy any data to user, size was 39630530Skarels * already set and checked above. 39730530Skarels */ 39840703Skarels if (error == 0 && (com&IOC_OUT) && size) 39940703Skarels error = copyout(data, uap->cmarg, (u_int)size); 40030530Skarels break; 4017423Sroot } 40231653Smckusick if (memp) 40331653Smckusick free(memp, M_IOCTLOPS); 40444405Skarels return (error); 4057423Sroot } 4067423Sroot 40712751Ssam int nselcoll; 40817593Skarels 4097423Sroot /* 41012751Ssam * Select system call. 4117423Sroot */ 41242922Smckusick select(p, uap, retval) 41342922Smckusick register struct proc *p; 41442922Smckusick register struct args { 41512751Ssam int nd; 41623523Skarels fd_set *in, *ou, *ex; 41712751Ssam struct timeval *tv; 41842922Smckusick } *uap; 41942922Smckusick int *retval; 42042922Smckusick { 42123523Skarels fd_set ibits[3], obits[3]; 42212751Ssam struct timeval atv; 42340703Skarels int s, ncoll, ni, error = 0, timo; 42412751Ssam 42526277Skarels bzero((caddr_t)ibits, sizeof(ibits)); 42626277Skarels bzero((caddr_t)obits, sizeof(obits)); 42712751Ssam if (uap->nd > NOFILE) 42812751Ssam uap->nd = NOFILE; /* forgiving, if slightly wrong */ 42923523Skarels ni = howmany(uap->nd, NFDBITS); 43012751Ssam 43112751Ssam #define getbits(name, x) \ 43212751Ssam if (uap->name) { \ 43340703Skarels error = copyin((caddr_t)uap->name, (caddr_t)&ibits[x], \ 43426277Skarels (unsigned)(ni * sizeof(fd_mask))); \ 43540703Skarels if (error) \ 43612751Ssam goto done; \ 43717593Skarels } 43812751Ssam getbits(in, 0); 43912751Ssam getbits(ou, 1); 44012751Ssam getbits(ex, 2); 44112751Ssam #undef getbits 44212751Ssam 44312751Ssam if (uap->tv) { 44440703Skarels error = copyin((caddr_t)uap->tv, (caddr_t)&atv, 44512751Ssam sizeof (atv)); 44640703Skarels if (error) 44712751Ssam goto done; 44812751Ssam if (itimerfix(&atv)) { 44940703Skarels error = EINVAL; 45012751Ssam goto done; 45112751Ssam } 45217934Skarels s = splhigh(); timevaladd(&atv, &time); splx(s); 45340703Skarels timo = hzto(&atv); 45440703Skarels } else 45540703Skarels timo = 0; 45612751Ssam retry: 45712751Ssam ncoll = nselcoll; 45842922Smckusick p->p_flag |= SSEL; 45942922Smckusick error = selscan(ibits, obits, uap->nd, retval); 46042922Smckusick if (error || *retval) 46112751Ssam goto done; 46217934Skarels s = splhigh(); 46312971Ssam /* this should be timercmp(&time, &atv, >=) */ 46412971Ssam if (uap->tv && (time.tv_sec > atv.tv_sec || 46512971Ssam time.tv_sec == atv.tv_sec && time.tv_usec >= atv.tv_usec)) { 46612751Ssam splx(s); 46712751Ssam goto done; 46812751Ssam } 46942922Smckusick if ((p->p_flag & SSEL) == 0 || nselcoll != ncoll) { 47012751Ssam splx(s); 47112751Ssam goto retry; 47212751Ssam } 47342922Smckusick p->p_flag &= ~SSEL; 47440703Skarels error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo); 47512751Ssam splx(s); 47640703Skarels if (error == 0) 47740703Skarels goto retry; 47812751Ssam done: 47942922Smckusick p->p_flag &= ~SSEL; 48040703Skarels /* select is not restarted after signals... */ 48140703Skarels if (error == ERESTART) 48240703Skarels error = EINTR; 48340703Skarels if (error == EWOULDBLOCK) 48440703Skarels error = 0; 48512751Ssam #define putbits(name, x) \ 48612751Ssam if (uap->name) { \ 48740703Skarels int error2 = copyout((caddr_t)&obits[x], (caddr_t)uap->name, \ 48826277Skarels (unsigned)(ni * sizeof(fd_mask))); \ 48940703Skarels if (error2) \ 49040703Skarels error = error2; \ 49112751Ssam } 49240703Skarels if (error == 0) { 49321106Skarels putbits(in, 0); 49421106Skarels putbits(ou, 1); 49521106Skarels putbits(ex, 2); 49612751Ssam #undef putbits 49721106Skarels } 49844405Skarels return (error); 49912751Ssam } 50012751Ssam 50142922Smckusick selscan(ibits, obits, nfd, retval) 50223523Skarels fd_set *ibits, *obits; 50342922Smckusick int nfd, *retval; 50412751Ssam { 50523523Skarels register int which, i, j; 50623523Skarels register fd_mask bits; 50712751Ssam int flag; 50812751Ssam struct file *fp; 50942922Smckusick int error = 0, n = 0; 51012751Ssam 51112751Ssam for (which = 0; which < 3; which++) { 51212751Ssam switch (which) { 51312751Ssam 51412751Ssam case 0: 51512751Ssam flag = FREAD; break; 51612751Ssam 51712751Ssam case 1: 51812751Ssam flag = FWRITE; break; 51912751Ssam 52012751Ssam case 2: 52112751Ssam flag = 0; break; 52212751Ssam } 52323523Skarels for (i = 0; i < nfd; i += NFDBITS) { 52423523Skarels bits = ibits[which].fds_bits[i/NFDBITS]; 52517593Skarels while ((j = ffs(bits)) && i + --j < nfd) { 52617593Skarels bits &= ~(1 << j); 52717593Skarels fp = u.u_ofile[i + j]; 52817593Skarels if (fp == NULL) { 52942922Smckusick error = EBADF; 53017593Skarels break; 53117593Skarels } 53217593Skarels if ((*fp->f_ops->fo_select)(fp, flag)) { 53323523Skarels FD_SET(i + j, &obits[which]); 53417593Skarels n++; 53517593Skarels } 53612751Ssam } 53712751Ssam } 53812751Ssam } 53942922Smckusick *retval = n; 54042922Smckusick return (error); 54112751Ssam } 54212751Ssam 5437423Sroot /*ARGSUSED*/ 54412751Ssam seltrue(dev, flag) 54512751Ssam dev_t dev; 54612751Ssam int flag; 5477423Sroot { 5487423Sroot 54912751Ssam return (1); 5507423Sroot } 5518103Sroot 55212751Ssam selwakeup(p, coll) 55312751Ssam register struct proc *p; 55412751Ssam int coll; 5558103Sroot { 5568103Sroot 55712751Ssam if (coll) { 55812751Ssam nselcoll++; 55912751Ssam wakeup((caddr_t)&selwait); 56012751Ssam } 56112751Ssam if (p) { 56217934Skarels int s = splhigh(); 56317270Skarels if (p->p_wchan == (caddr_t)&selwait) { 56417270Skarels if (p->p_stat == SSLEEP) 56517270Skarels setrun(p); 56617270Skarels else 56717270Skarels unsleep(p); 56817270Skarels } else if (p->p_flag & SSEL) 56912751Ssam p->p_flag &= ~SSEL; 57012751Ssam splx(s); 57112751Ssam } 5728103Sroot } 573