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*44939Skarels * @(#)sys_generic.c 7.23 (Berkeley) 07/22/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 */ 2742922Smckusick read(p, uap, retval) 2842922Smckusick struct proc *p; 2942922Smckusick register struct args { 307423Sroot int fdes; 317423Sroot char *cbuf; 327423Sroot unsigned count; 3342922Smckusick } *uap; 3442922Smckusick int *retval; 3542922Smckusick { 3637728Smckusick register struct file *fp; 377746Sroot struct uio auio; 387746Sroot struct iovec aiov; 3937728Smckusick long cnt, error = 0; 4037728Smckusick #ifdef KTRACE 4137728Smckusick struct iovec ktriov; 4237728Smckusick #endif 437423Sroot 4437728Smckusick if (((unsigned)uap->fdes) >= NOFILE || 4537728Smckusick (fp = u.u_ofile[uap->fdes]) == NULL || 4637728Smckusick (fp->f_flag & FREAD) == 0) 4744405Skarels return (EBADF); 487820Sroot aiov.iov_base = (caddr_t)uap->cbuf; 497820Sroot aiov.iov_len = uap->count; 507820Sroot auio.uio_iov = &aiov; 517820Sroot auio.uio_iovcnt = 1; 5237728Smckusick auio.uio_resid = uap->count; 5337728Smckusick auio.uio_rw = UIO_READ; 5437728Smckusick auio.uio_segflg = UIO_USERSPACE; 5537728Smckusick #ifdef KTRACE 5637728Smckusick /* 5737728Smckusick * if tracing, save a copy of iovec 5837728Smckusick */ 5942922Smckusick if (KTRPOINT(p, KTR_GENIO)) 6037728Smckusick ktriov = aiov; 6137728Smckusick #endif 6237728Smckusick cnt = uap->count; 6340703Skarels if (error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred)) 6440703Skarels if (auio.uio_resid != cnt && (error == ERESTART || 6540703Skarels error == EINTR || error == EWOULDBLOCK)) 6640703Skarels error = 0; 6737728Smckusick cnt -= auio.uio_resid; 6837728Smckusick #ifdef KTRACE 6942922Smckusick if (KTRPOINT(p, KTR_GENIO) && error == 0) 7043448Smckusick ktrgenio(p->p_tracep, uap->fdes, UIO_READ, &ktriov, cnt, error); 7137728Smckusick #endif 7242922Smckusick *retval = cnt; 7344405Skarels return (error); 747820Sroot } 757820Sroot 7642922Smckusick /* 7742922Smckusick * Scatter read system call. 7842922Smckusick */ 7942922Smckusick readv(p, uap, retval) 8042922Smckusick struct proc *p; 8142922Smckusick register struct args { 827820Sroot int fdes; 837820Sroot struct iovec *iovp; 8426474Skarels unsigned iovcnt; 8542922Smckusick } *uap; 8642922Smckusick int *retval; 8742922Smckusick { 8837728Smckusick register struct file *fp; 897820Sroot struct uio auio; 9037728Smckusick register struct iovec *iov; 91*44939Skarels struct iovec *saveiov; 9237728Smckusick struct iovec aiov[UIO_SMALLIOV]; 9337728Smckusick long i, cnt, error = 0; 94*44939Skarels unsigned iovlen; 9537728Smckusick #ifdef KTRACE 9637728Smckusick struct iovec *ktriov = NULL; 9737728Smckusick #endif 987820Sroot 9937728Smckusick if (((unsigned)uap->fdes) >= NOFILE || 10037728Smckusick (fp = u.u_ofile[uap->fdes]) == NULL || 10137728Smckusick (fp->f_flag & FREAD) == 0) 10244405Skarels return (EBADF); 103*44939Skarels /* note: can't use iovlen until iovcnt is validated */ 104*44939Skarels iovlen = uap->iovcnt * sizeof (struct iovec); 10537127Skarels if (uap->iovcnt > UIO_SMALLIOV) { 10637728Smckusick if (uap->iovcnt > UIO_MAXIOV) 10744405Skarels return (EINVAL); 108*44939Skarels MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); 109*44939Skarels saveiov = iov; 11037127Skarels } else 11137127Skarels iov = aiov; 11237127Skarels auio.uio_iov = iov; 1137820Sroot auio.uio_iovcnt = uap->iovcnt; 11437728Smckusick auio.uio_rw = UIO_READ; 11537728Smckusick auio.uio_segflg = UIO_USERSPACE; 116*44939Skarels if (error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen)) 11737127Skarels goto done; 11837728Smckusick auio.uio_resid = 0; 11937728Smckusick for (i = 0; i < uap->iovcnt; i++) { 12037728Smckusick if (iov->iov_len < 0) { 12137728Smckusick error = EINVAL; 12237728Smckusick goto done; 12337728Smckusick } 12437728Smckusick auio.uio_resid += iov->iov_len; 12537728Smckusick if (auio.uio_resid < 0) { 12637728Smckusick error = EINVAL; 12737728Smckusick goto done; 12837728Smckusick } 12937728Smckusick iov++; 13037728Smckusick } 13137728Smckusick #ifdef KTRACE 13237728Smckusick /* 13337728Smckusick * if tracing, save a copy of iovec 13437728Smckusick */ 13542922Smckusick if (KTRPOINT(p, KTR_GENIO)) { 13637728Smckusick MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 13737728Smckusick bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 13837728Smckusick } 13937728Smckusick #endif 14037728Smckusick cnt = auio.uio_resid; 14140703Skarels if (error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred)) 14240703Skarels if (auio.uio_resid != cnt && (error == ERESTART || 14340703Skarels error == EINTR || error == EWOULDBLOCK)) 14440703Skarels error = 0; 14537728Smckusick cnt -= auio.uio_resid; 14637728Smckusick #ifdef KTRACE 14737728Smckusick if (ktriov != NULL) { 14841178Smarc if (error == 0) 14943448Smckusick ktrgenio(p->p_tracep, uap->fdes, UIO_READ, ktriov, 15043448Smckusick cnt, error); 15137728Smckusick FREE(ktriov, M_TEMP); 15237728Smckusick } 15337728Smckusick #endif 15442922Smckusick *retval = cnt; 15537127Skarels done: 15637728Smckusick if (uap->iovcnt > UIO_SMALLIOV) 157*44939Skarels FREE(saveiov, M_IOV); 15844405Skarels return (error); 1597423Sroot } 1607423Sroot 1617423Sroot /* 1627423Sroot * Write system call 1637423Sroot */ 16442922Smckusick write(p, uap, retval) 16542922Smckusick struct proc *p; 16642922Smckusick register struct args { 1677423Sroot int fdes; 1687423Sroot char *cbuf; 16926474Skarels unsigned count; 17042922Smckusick } *uap; 17142922Smckusick int *retval; 17242922Smckusick { 17337728Smckusick register struct file *fp; 1747820Sroot struct uio auio; 1757820Sroot struct iovec aiov; 17637728Smckusick long cnt, error = 0; 17737728Smckusick #ifdef KTRACE 17837728Smckusick struct iovec ktriov; 17937728Smckusick #endif 1807423Sroot 18137728Smckusick if (((unsigned)uap->fdes) >= NOFILE || 18237728Smckusick (fp = u.u_ofile[uap->fdes]) == NULL || 18337728Smckusick (fp->f_flag & FWRITE) == 0) 18444405Skarels return (EBADF); 18537728Smckusick aiov.iov_base = (caddr_t)uap->cbuf; 18637728Smckusick aiov.iov_len = uap->count; 1877820Sroot auio.uio_iov = &aiov; 1887820Sroot auio.uio_iovcnt = 1; 18937728Smckusick auio.uio_resid = uap->count; 19037728Smckusick auio.uio_rw = UIO_WRITE; 19137728Smckusick auio.uio_segflg = UIO_USERSPACE; 19237728Smckusick #ifdef KTRACE 19337728Smckusick /* 19437728Smckusick * if tracing, save a copy of iovec 19537728Smckusick */ 19642922Smckusick if (KTRPOINT(p, KTR_GENIO)) 19737728Smckusick ktriov = aiov; 19837728Smckusick #endif 19937728Smckusick cnt = uap->count; 20040703Skarels if (error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred)) { 20140703Skarels if (auio.uio_resid != cnt && (error == ERESTART || 20240703Skarels error == EINTR || error == EWOULDBLOCK)) 20340703Skarels error = 0; 20440703Skarels if (error == EPIPE) 20542922Smckusick psignal(p, SIGPIPE); 20640703Skarels } 20737728Smckusick cnt -= auio.uio_resid; 20837728Smckusick #ifdef KTRACE 20942922Smckusick if (KTRPOINT(p, KTR_GENIO) && error == 0) 21042922Smckusick ktrgenio(p->p_tracep, uap->fdes, UIO_WRITE, 21143448Smckusick &ktriov, cnt, error); 21237728Smckusick #endif 21342922Smckusick *retval = cnt; 21444405Skarels return (error); 2157820Sroot } 2167820Sroot 21742922Smckusick /* 21842922Smckusick * Gather write system call 21942922Smckusick */ 22042922Smckusick writev(p, uap, retval) 22142922Smckusick struct proc *p; 22242922Smckusick register struct args { 2237820Sroot int fdes; 2247820Sroot struct iovec *iovp; 22526474Skarels unsigned iovcnt; 22642922Smckusick } *uap; 22742922Smckusick int *retval; 22842922Smckusick { 22937728Smckusick register struct file *fp; 2307820Sroot struct uio auio; 23137728Smckusick register struct iovec *iov; 232*44939Skarels struct iovec *saveiov; 23337728Smckusick struct iovec aiov[UIO_SMALLIOV]; 23437728Smckusick long i, cnt, error = 0; 235*44939Skarels unsigned iovlen; 23637728Smckusick #ifdef KTRACE 23737728Smckusick struct iovec *ktriov = NULL; 23837728Smckusick #endif 2397820Sroot 24037728Smckusick if (((unsigned)uap->fdes) >= NOFILE || 24137728Smckusick (fp = u.u_ofile[uap->fdes]) == NULL || 24237728Smckusick (fp->f_flag & FWRITE) == 0) 24344405Skarels return (EBADF); 244*44939Skarels /* note: can't use iovlen until iovcnt is validated */ 245*44939Skarels iovlen = uap->iovcnt * sizeof (struct iovec); 24637127Skarels if (uap->iovcnt > UIO_SMALLIOV) { 24737728Smckusick if (uap->iovcnt > UIO_MAXIOV) 24844405Skarels return (EINVAL); 249*44939Skarels MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); 250*44939Skarels saveiov = iov; 25137127Skarels } else 25237127Skarels iov = aiov; 25337127Skarels auio.uio_iov = iov; 2547820Sroot auio.uio_iovcnt = uap->iovcnt; 25537728Smckusick auio.uio_rw = UIO_WRITE; 25637728Smckusick auio.uio_segflg = UIO_USERSPACE; 257*44939Skarels if (error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen)) 25837127Skarels goto done; 25937728Smckusick auio.uio_resid = 0; 26037728Smckusick for (i = 0; i < uap->iovcnt; i++) { 2617820Sroot if (iov->iov_len < 0) { 26237728Smckusick error = EINVAL; 26337728Smckusick goto done; 2647820Sroot } 26537728Smckusick auio.uio_resid += iov->iov_len; 26637728Smckusick if (auio.uio_resid < 0) { 26737728Smckusick error = EINVAL; 26837728Smckusick goto done; 2697820Sroot } 27013270Ssam iov++; 2717820Sroot } 27237127Skarels #ifdef KTRACE 27337728Smckusick /* 27437728Smckusick * if tracing, save a copy of iovec 27537728Smckusick */ 27642922Smckusick if (KTRPOINT(p, KTR_GENIO)) { 27737127Skarels MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 27837728Smckusick bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 27937127Skarels } 28037127Skarels #endif 28137728Smckusick cnt = auio.uio_resid; 28240703Skarels if (error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred)) { 28340703Skarels if (auio.uio_resid != cnt && (error == ERESTART || 28440703Skarels error == EINTR || error == EWOULDBLOCK)) 28540703Skarels error = 0; 28640703Skarels if (error == EPIPE) 28742922Smckusick psignal(p, SIGPIPE); 28840703Skarels } 28937728Smckusick cnt -= auio.uio_resid; 29037127Skarels #ifdef KTRACE 29137127Skarels if (ktriov != NULL) { 29241178Smarc if (error == 0) 29342922Smckusick ktrgenio(p->p_tracep, uap->fdes, UIO_WRITE, 29443448Smckusick ktriov, cnt, error); 29537127Skarels FREE(ktriov, M_TEMP); 29637127Skarels } 29737127Skarels #endif 29842922Smckusick *retval = cnt; 29937728Smckusick done: 30037728Smckusick if (uap->iovcnt > UIO_SMALLIOV) 301*44939Skarels FREE(saveiov, M_IOV); 30244405Skarels return (error); 3037423Sroot } 3047423Sroot 3057423Sroot /* 3067423Sroot * Ioctl system call 3077423Sroot */ 30842922Smckusick /* ARGSUSED */ 30942922Smckusick ioctl(p, uap, retval) 31042922Smckusick struct proc *p; 31142922Smckusick register struct args { 3127423Sroot int fdes; 3137423Sroot int cmd; 3147423Sroot caddr_t cmarg; 31542922Smckusick } *uap; 31642922Smckusick int *retval; 31742922Smckusick { 31842922Smckusick register struct file *fp; 31940703Skarels register int com, error; 3207820Sroot register u_int size; 32131653Smckusick caddr_t memp = 0; 32230530Skarels #define STK_PARAMS 128 32333480Skarels char stkbuf[STK_PARAMS]; 32433480Skarels caddr_t data = stkbuf; 3257423Sroot 32637728Smckusick if ((unsigned)uap->fdes >= NOFILE || 32737728Smckusick (fp = u.u_ofile[uap->fdes]) == NULL) 32844405Skarels return (EBADF); 32940703Skarels if ((fp->f_flag & (FREAD|FWRITE)) == 0) 33044405Skarels return (EBADF); 3317624Ssam com = uap->cmd; 3327624Ssam 3337624Ssam if (com == FIOCLEX) { 3349592Ssam u.u_pofile[uap->fdes] |= UF_EXCLOSE; 33544405Skarels return (0); 3367423Sroot } 3377624Ssam if (com == FIONCLEX) { 3389592Ssam u.u_pofile[uap->fdes] &= ~UF_EXCLOSE; 33944405Skarels return (0); 3407423Sroot } 3417624Ssam 3427624Ssam /* 3437624Ssam * Interpret high order word to find 3447624Ssam * amount of data to be copied to/from the 3457624Ssam * user's address space. 3467624Ssam */ 34730530Skarels size = IOCPARM_LEN(com); 34840703Skarels if (size > IOCPARM_MAX) 34944405Skarels return (ENOTTY); 35033480Skarels if (size > sizeof (stkbuf)) { 35143383Smckusick memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK); 35231653Smckusick data = memp; 35330530Skarels } 35410601Ssam if (com&IOC_IN) { 35510601Ssam if (size) { 35640703Skarels error = copyin(uap->cmarg, data, (u_int)size); 35740703Skarels if (error) { 35831653Smckusick if (memp) 35931653Smckusick free(memp, M_IOCTLOPS); 36044405Skarels return (error); 36131653Smckusick } 36210601Ssam } else 36310601Ssam *(caddr_t *)data = uap->cmarg; 36410601Ssam } else if ((com&IOC_OUT) && size) 36510601Ssam /* 36637127Skarels * Zero the buffer so the user always 36737127Skarels * gets back something deterministic. 36810601Ssam */ 36930530Skarels bzero(data, size); 37011284Ssam else if (com&IOC_VOID) 37111284Ssam *(caddr_t *)data = uap->cmarg; 3727423Sroot 37312751Ssam switch (com) { 3747624Ssam 37512751Ssam case FIONBIO: 37640703Skarels error = fset(fp, FNDELAY, *(int *)data); 37730530Skarels break; 37812751Ssam 37912751Ssam case FIOASYNC: 38040703Skarels error = fset(fp, FASYNC, *(int *)data); 38130530Skarels break; 38212751Ssam 38312751Ssam case FIOSETOWN: 38440703Skarels error = fsetown(fp, *(int *)data); 38530530Skarels break; 38612751Ssam 38712751Ssam case FIOGETOWN: 38840703Skarels error = fgetown(fp, (int *)data); 38930530Skarels break; 39030530Skarels default: 39140703Skarels error = (*fp->f_ops->fo_ioctl)(fp, com, data); 39230530Skarels /* 39330530Skarels * Copy any data to user, size was 39430530Skarels * already set and checked above. 39530530Skarels */ 39640703Skarels if (error == 0 && (com&IOC_OUT) && size) 39740703Skarels error = copyout(data, uap->cmarg, (u_int)size); 39830530Skarels break; 3997423Sroot } 40031653Smckusick if (memp) 40131653Smckusick free(memp, M_IOCTLOPS); 40244405Skarels return (error); 4037423Sroot } 4047423Sroot 40512751Ssam int nselcoll; 40617593Skarels 4077423Sroot /* 40812751Ssam * Select system call. 4097423Sroot */ 41042922Smckusick select(p, uap, retval) 41142922Smckusick register struct proc *p; 41242922Smckusick register struct args { 41312751Ssam int nd; 41423523Skarels fd_set *in, *ou, *ex; 41512751Ssam struct timeval *tv; 41642922Smckusick } *uap; 41742922Smckusick int *retval; 41842922Smckusick { 41923523Skarels fd_set ibits[3], obits[3]; 42012751Ssam struct timeval atv; 42140703Skarels int s, ncoll, ni, error = 0, timo; 42212751Ssam 42326277Skarels bzero((caddr_t)ibits, sizeof(ibits)); 42426277Skarels bzero((caddr_t)obits, sizeof(obits)); 42512751Ssam if (uap->nd > NOFILE) 42612751Ssam uap->nd = NOFILE; /* forgiving, if slightly wrong */ 42723523Skarels ni = howmany(uap->nd, NFDBITS); 42812751Ssam 42912751Ssam #define getbits(name, x) \ 43012751Ssam if (uap->name) { \ 43140703Skarels error = copyin((caddr_t)uap->name, (caddr_t)&ibits[x], \ 43226277Skarels (unsigned)(ni * sizeof(fd_mask))); \ 43340703Skarels if (error) \ 43412751Ssam goto done; \ 43517593Skarels } 43612751Ssam getbits(in, 0); 43712751Ssam getbits(ou, 1); 43812751Ssam getbits(ex, 2); 43912751Ssam #undef getbits 44012751Ssam 44112751Ssam if (uap->tv) { 44240703Skarels error = copyin((caddr_t)uap->tv, (caddr_t)&atv, 44312751Ssam sizeof (atv)); 44440703Skarels if (error) 44512751Ssam goto done; 44612751Ssam if (itimerfix(&atv)) { 44740703Skarels error = EINVAL; 44812751Ssam goto done; 44912751Ssam } 45017934Skarels s = splhigh(); timevaladd(&atv, &time); splx(s); 45140703Skarels timo = hzto(&atv); 45240703Skarels } else 45340703Skarels timo = 0; 45412751Ssam retry: 45512751Ssam ncoll = nselcoll; 45642922Smckusick p->p_flag |= SSEL; 45742922Smckusick error = selscan(ibits, obits, uap->nd, retval); 45842922Smckusick if (error || *retval) 45912751Ssam goto done; 46017934Skarels s = splhigh(); 46112971Ssam /* this should be timercmp(&time, &atv, >=) */ 46212971Ssam if (uap->tv && (time.tv_sec > atv.tv_sec || 46312971Ssam time.tv_sec == atv.tv_sec && time.tv_usec >= atv.tv_usec)) { 46412751Ssam splx(s); 46512751Ssam goto done; 46612751Ssam } 46742922Smckusick if ((p->p_flag & SSEL) == 0 || nselcoll != ncoll) { 46812751Ssam splx(s); 46912751Ssam goto retry; 47012751Ssam } 47142922Smckusick p->p_flag &= ~SSEL; 47240703Skarels error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo); 47312751Ssam splx(s); 47440703Skarels if (error == 0) 47540703Skarels goto retry; 47612751Ssam done: 47742922Smckusick p->p_flag &= ~SSEL; 47840703Skarels /* select is not restarted after signals... */ 47940703Skarels if (error == ERESTART) 48040703Skarels error = EINTR; 48140703Skarels if (error == EWOULDBLOCK) 48240703Skarels error = 0; 48312751Ssam #define putbits(name, x) \ 48412751Ssam if (uap->name) { \ 48540703Skarels int error2 = copyout((caddr_t)&obits[x], (caddr_t)uap->name, \ 48626277Skarels (unsigned)(ni * sizeof(fd_mask))); \ 48740703Skarels if (error2) \ 48840703Skarels error = error2; \ 48912751Ssam } 49040703Skarels if (error == 0) { 49121106Skarels putbits(in, 0); 49221106Skarels putbits(ou, 1); 49321106Skarels putbits(ex, 2); 49412751Ssam #undef putbits 49521106Skarels } 49644405Skarels return (error); 49712751Ssam } 49812751Ssam 49942922Smckusick selscan(ibits, obits, nfd, retval) 50023523Skarels fd_set *ibits, *obits; 50142922Smckusick int nfd, *retval; 50212751Ssam { 50323523Skarels register int which, i, j; 50423523Skarels register fd_mask bits; 50512751Ssam int flag; 50612751Ssam struct file *fp; 50742922Smckusick int error = 0, n = 0; 50812751Ssam 50912751Ssam for (which = 0; which < 3; which++) { 51012751Ssam switch (which) { 51112751Ssam 51212751Ssam case 0: 51312751Ssam flag = FREAD; break; 51412751Ssam 51512751Ssam case 1: 51612751Ssam flag = FWRITE; break; 51712751Ssam 51812751Ssam case 2: 51912751Ssam flag = 0; break; 52012751Ssam } 52123523Skarels for (i = 0; i < nfd; i += NFDBITS) { 52223523Skarels bits = ibits[which].fds_bits[i/NFDBITS]; 52317593Skarels while ((j = ffs(bits)) && i + --j < nfd) { 52417593Skarels bits &= ~(1 << j); 52517593Skarels fp = u.u_ofile[i + j]; 52617593Skarels if (fp == NULL) { 52742922Smckusick error = EBADF; 52817593Skarels break; 52917593Skarels } 53017593Skarels if ((*fp->f_ops->fo_select)(fp, flag)) { 53123523Skarels FD_SET(i + j, &obits[which]); 53217593Skarels n++; 53317593Skarels } 53412751Ssam } 53512751Ssam } 53612751Ssam } 53742922Smckusick *retval = n; 53842922Smckusick return (error); 53912751Ssam } 54012751Ssam 5417423Sroot /*ARGSUSED*/ 54212751Ssam seltrue(dev, flag) 54312751Ssam dev_t dev; 54412751Ssam int flag; 5457423Sroot { 5467423Sroot 54712751Ssam return (1); 5487423Sroot } 5498103Sroot 55012751Ssam selwakeup(p, coll) 55112751Ssam register struct proc *p; 55212751Ssam int coll; 5538103Sroot { 5548103Sroot 55512751Ssam if (coll) { 55612751Ssam nselcoll++; 55712751Ssam wakeup((caddr_t)&selwait); 55812751Ssam } 55912751Ssam if (p) { 56017934Skarels int s = splhigh(); 56117270Skarels if (p->p_wchan == (caddr_t)&selwait) { 56217270Skarels if (p->p_stat == SSLEEP) 56317270Skarels setrun(p); 56417270Skarels else 56517270Skarels unsleep(p); 56617270Skarels } else if (p->p_flag & SSEL) 56712751Ssam p->p_flag &= ~SSEL; 56812751Ssam splx(s); 56912751Ssam } 5708103Sroot } 571