home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / kern / sys_generic.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-17  |  14.5 KB  |  649 lines

  1. /*
  2.  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  *
  33.  *    @(#)sys_generic.c    7.30 (Berkeley) 5/30/91
  34.  */
  35.  
  36. #include "param.h"
  37. #include "systm.h"
  38. #include "filedesc.h"
  39. #include "ioctl.h"
  40. #include "file.h"
  41. #include "socketvar.h"
  42. #include "proc.h"
  43. #include "uio.h"
  44. #include "kernel.h"
  45. #include "stat.h"
  46. #include "malloc.h"
  47. #ifdef KTRACE
  48. #include "ktrace.h"
  49. #endif
  50.  
  51. /*
  52.  * Read system call.
  53.  */
  54. /* ARGSUSED */
  55. read(p, uap, retval)
  56.     struct proc *p;
  57.     register struct args {
  58.         int    fdes;
  59.         char    *cbuf;
  60.         unsigned count;
  61.     } *uap;
  62.     int *retval;
  63. {
  64.     register struct file *fp;
  65.     register struct filedesc *fdp = p->p_fd;
  66.     struct uio auio;
  67.     struct iovec aiov;
  68.     long cnt, error = 0;
  69. #ifdef KTRACE
  70.     struct iovec ktriov;
  71. #endif
  72.  
  73.     if (((unsigned)uap->fdes) >= fdp->fd_nfiles ||
  74.         (fp = fdp->fd_ofiles[uap->fdes]) == NULL ||
  75.         (fp->f_flag & FREAD) == 0)
  76.         return (EBADF);
  77.     aiov.iov_base = (caddr_t)uap->cbuf;
  78.     aiov.iov_len = uap->count;
  79.     auio.uio_iov = &aiov;
  80.     auio.uio_iovcnt = 1;
  81.     auio.uio_resid = uap->count;
  82.     auio.uio_rw = UIO_READ;
  83.     auio.uio_segflg = UIO_USERSPACE;
  84.     auio.uio_procp = p;
  85. #ifdef KTRACE
  86.     /*
  87.      * if tracing, save a copy of iovec
  88.      */
  89.     if (KTRPOINT(p, KTR_GENIO))
  90.         ktriov = aiov;
  91. #endif
  92.     cnt = uap->count;
  93.     if (error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred))
  94.         if (auio.uio_resid != cnt && (error == ERESTART ||
  95.             error == EINTR || error == EWOULDBLOCK))
  96.             error = 0;
  97.     cnt -= auio.uio_resid;
  98. #ifdef KTRACE
  99.     if (KTRPOINT(p, KTR_GENIO) && error == 0)
  100.         ktrgenio(p->p_tracep, uap->fdes, UIO_READ, &ktriov, cnt, error);
  101. #endif
  102.     *retval = cnt;
  103.     return (error);
  104. }
  105.  
  106. /*
  107.  * Scatter read system call.
  108.  */
  109. /* ARGSUSED */
  110. readv(p, uap, retval)
  111.     struct proc *p;
  112.     register struct args {
  113.         int    fdes;
  114.         struct    iovec *iovp;
  115.         unsigned iovcnt;
  116.     } *uap;
  117.     int *retval;
  118. {
  119.     register struct file *fp;
  120.     register struct filedesc *fdp = p->p_fd;
  121.     struct uio auio;
  122.     register struct iovec *iov;
  123.     struct iovec *saveiov;
  124.     struct iovec aiov[UIO_SMALLIOV];
  125.     long i, cnt, error = 0;
  126.     unsigned iovlen;
  127. #ifdef KTRACE
  128.     struct iovec *ktriov = NULL;
  129. #endif
  130.  
  131.     if (((unsigned)uap->fdes) >= fdp->fd_nfiles ||
  132.         (fp = fdp->fd_ofiles[uap->fdes]) == NULL ||
  133.         (fp->f_flag & FREAD) == 0)
  134.         return (EBADF);
  135.     /* note: can't use iovlen until iovcnt is validated */
  136.     iovlen = uap->iovcnt * sizeof (struct iovec);
  137.     if (uap->iovcnt > UIO_SMALLIOV) {
  138.         if (uap->iovcnt > UIO_MAXIOV)
  139.             return (EINVAL);
  140.         MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
  141.         saveiov = iov;
  142.     } else
  143.         iov = aiov;
  144.     auio.uio_iov = iov;
  145.     auio.uio_iovcnt = uap->iovcnt;
  146.     auio.uio_rw = UIO_READ;
  147.     auio.uio_segflg = UIO_USERSPACE;
  148.     auio.uio_procp = p;
  149.     if (error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen))
  150.         goto done;
  151.     auio.uio_resid = 0;
  152.     for (i = 0; i < uap->iovcnt; i++) {
  153.         if (iov->iov_len < 0) {
  154.             error = EINVAL;
  155.             goto done;
  156.         }
  157.         auio.uio_resid += iov->iov_len;
  158.         if (auio.uio_resid < 0) {
  159.             error = EINVAL;
  160.             goto done;
  161.         }
  162.         iov++;
  163.     }
  164. #ifdef KTRACE
  165.     /*
  166.      * if tracing, save a copy of iovec
  167.      */
  168.     if (KTRPOINT(p, KTR_GENIO))  {
  169.         MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
  170.         bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
  171.     }
  172. #endif
  173.     cnt = auio.uio_resid;
  174.     if (error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred))
  175.         if (auio.uio_resid != cnt && (error == ERESTART ||
  176.             error == EINTR || error == EWOULDBLOCK))
  177.             error = 0;
  178.     cnt -= auio.uio_resid;
  179. #ifdef KTRACE
  180.     if (ktriov != NULL) {
  181.         if (error == 0)
  182.             ktrgenio(p->p_tracep, uap->fdes, UIO_READ, ktriov,
  183.                 cnt, error);
  184.         FREE(ktriov, M_TEMP);
  185.     }
  186. #endif
  187.     *retval = cnt;
  188. done:
  189.     if (uap->iovcnt > UIO_SMALLIOV)
  190.         FREE(saveiov, M_IOV);
  191.     return (error);
  192. }
  193.  
  194. /*
  195.  * Write system call
  196.  */
  197. write(p, uap, retval)
  198.     struct proc *p;
  199.     register struct args {
  200.         int    fdes;
  201.         char    *cbuf;
  202.         unsigned count;
  203.     } *uap;
  204.     int *retval;
  205. {
  206.     register struct file *fp;
  207.     register struct filedesc *fdp = p->p_fd;
  208.     struct uio auio;
  209.     struct iovec aiov;
  210.     long cnt, error = 0;
  211. #ifdef KTRACE
  212.     struct iovec ktriov;
  213. #endif
  214.  
  215.     if (((unsigned)uap->fdes) >= fdp->fd_nfiles ||
  216.         (fp = fdp->fd_ofiles[uap->fdes]) == NULL ||
  217.         (fp->f_flag & FWRITE) == 0)
  218.         return (EBADF);
  219.     aiov.iov_base = (caddr_t)uap->cbuf;
  220.     aiov.iov_len = uap->count;
  221.     auio.uio_iov = &aiov;
  222.     auio.uio_iovcnt = 1;
  223.     auio.uio_resid = uap->count;
  224.     auio.uio_rw = UIO_WRITE;
  225.     auio.uio_segflg = UIO_USERSPACE;
  226.     auio.uio_procp = p;
  227. #ifdef KTRACE
  228.     /*
  229.      * if tracing, save a copy of iovec
  230.      */
  231.     if (KTRPOINT(p, KTR_GENIO))
  232.         ktriov = aiov;
  233. #endif
  234.     cnt = uap->count;
  235.     if (error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred)) {
  236.         if (auio.uio_resid != cnt && (error == ERESTART ||
  237.             error == EINTR || error == EWOULDBLOCK))
  238.             error = 0;
  239.         if (error == EPIPE)
  240.             psignal(p, SIGPIPE);
  241.     }
  242.     cnt -= auio.uio_resid;
  243. #ifdef KTRACE
  244.     if (KTRPOINT(p, KTR_GENIO) && error == 0)
  245.         ktrgenio(p->p_tracep, uap->fdes, UIO_WRITE,
  246.             &ktriov, cnt, error);
  247. #endif
  248.     *retval = cnt;
  249.     return (error);
  250. }
  251.  
  252. /*
  253.  * Gather write system call
  254.  */
  255. writev(p, uap, retval)
  256.     struct proc *p;
  257.     register struct args {
  258.         int    fdes;
  259.         struct    iovec *iovp;
  260.         unsigned iovcnt;
  261.     } *uap;
  262.     int *retval;
  263. {
  264.     register struct file *fp;
  265.     register struct filedesc *fdp = p->p_fd;
  266.     struct uio auio;
  267.     register struct iovec *iov;
  268.     struct iovec *saveiov;
  269.     struct iovec aiov[UIO_SMALLIOV];
  270.     long i, cnt, error = 0;
  271.     unsigned iovlen;
  272. #ifdef KTRACE
  273.     struct iovec *ktriov = NULL;
  274. #endif
  275.  
  276.     if (((unsigned)uap->fdes) >= fdp->fd_nfiles ||
  277.         (fp = fdp->fd_ofiles[uap->fdes]) == NULL ||
  278.         (fp->f_flag & FWRITE) == 0)
  279.         return (EBADF);
  280.     /* note: can't use iovlen until iovcnt is validated */
  281.     iovlen = uap->iovcnt * sizeof (struct iovec);
  282.     if (uap->iovcnt > UIO_SMALLIOV) {
  283.         if (uap->iovcnt > UIO_MAXIOV)
  284.             return (EINVAL);
  285.         MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
  286.         saveiov = iov;
  287.     } else
  288.         iov = aiov;
  289.     auio.uio_iov = iov;
  290.     auio.uio_iovcnt = uap->iovcnt;
  291.     auio.uio_rw = UIO_WRITE;
  292.     auio.uio_segflg = UIO_USERSPACE;
  293.     auio.uio_procp = p;
  294.     if (error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen))
  295.         goto done;
  296.     auio.uio_resid = 0;
  297.     for (i = 0; i < uap->iovcnt; i++) {
  298.         if (iov->iov_len < 0) {
  299.             error = EINVAL;
  300.             goto done;
  301.         }
  302.         auio.uio_resid += iov->iov_len;
  303.         if (auio.uio_resid < 0) {
  304.             error = EINVAL;
  305.             goto done;
  306.         }
  307.         iov++;
  308.     }
  309. #ifdef KTRACE
  310.     /*
  311.      * if tracing, save a copy of iovec
  312.      */
  313.     if (KTRPOINT(p, KTR_GENIO))  {
  314.         MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
  315.         bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
  316.     }
  317. #endif
  318.     cnt = auio.uio_resid;
  319.     if (error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred)) {
  320.         if (auio.uio_resid != cnt && (error == ERESTART ||
  321.             error == EINTR || error == EWOULDBLOCK))
  322.             error = 0;
  323.         if (error == EPIPE)
  324.             psignal(p, SIGPIPE);
  325.     }
  326.     cnt -= auio.uio_resid;
  327. #ifdef KTRACE
  328.     if (ktriov != NULL) {
  329.         if (error == 0)
  330.             ktrgenio(p->p_tracep, uap->fdes, UIO_WRITE,
  331.                 ktriov, cnt, error);
  332.         FREE(ktriov, M_TEMP);
  333.     }
  334. #endif
  335.     *retval = cnt;
  336. done:
  337.     if (uap->iovcnt > UIO_SMALLIOV)
  338.         FREE(saveiov, M_IOV);
  339.     return (error);
  340. }
  341.  
  342. /*
  343.  * Ioctl system call
  344.  */
  345. /* ARGSUSED */
  346. ioctl(p, uap, retval)
  347.     struct proc *p;
  348.     register struct args {
  349.         int    fdes;
  350.         int    cmd;
  351.         caddr_t    cmarg;
  352.     } *uap;
  353.     int *retval;
  354. {
  355.     register struct file *fp;
  356.     register struct filedesc *fdp = p->p_fd;
  357.     register int com, error;
  358.     register u_int size;
  359.     caddr_t memp = 0;
  360. #define STK_PARAMS    128
  361.     char stkbuf[STK_PARAMS];
  362.     caddr_t data = stkbuf;
  363.     int tmp;
  364.  
  365.     if ((unsigned)uap->fdes >= fdp->fd_nfiles ||
  366.         (fp = fdp->fd_ofiles[uap->fdes]) == NULL)
  367.         return (EBADF);
  368.     if ((fp->f_flag & (FREAD|FWRITE)) == 0)
  369.         return (EBADF);
  370.     com = uap->cmd;
  371.  
  372.     if (com == FIOCLEX) {
  373.         fdp->fd_ofileflags[uap->fdes] |= UF_EXCLOSE;
  374.         return (0);
  375.     }
  376.     if (com == FIONCLEX) {
  377.         fdp->fd_ofileflags[uap->fdes] &= ~UF_EXCLOSE;
  378.         return (0);
  379.     }
  380.  
  381.     /*
  382.      * Interpret high order word to find
  383.      * amount of data to be copied to/from the
  384.      * user's address space.
  385.      */
  386.     size = IOCPARM_LEN(com);
  387.     if (size > IOCPARM_MAX)
  388.         return (ENOTTY);
  389.     if (size > sizeof (stkbuf)) {
  390.         memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK);
  391.         data = memp;
  392.     }
  393.     if (com&IOC_IN) {
  394.         if (size) {
  395.             error = copyin(uap->cmarg, data, (u_int)size);
  396.             if (error) {
  397.                 if (memp)
  398.                     free(memp, M_IOCTLOPS);
  399.                 return (error);
  400.             }
  401.         } else
  402.             *(caddr_t *)data = uap->cmarg;
  403.     } else if ((com&IOC_OUT) && size)
  404.         /*
  405.          * Zero the buffer so the user always
  406.          * gets back something deterministic.
  407.          */
  408.         bzero(data, size);
  409.     else if (com&IOC_VOID)
  410.         *(caddr_t *)data = uap->cmarg;
  411.  
  412.     switch (com) {
  413.  
  414.     case FIONBIO:
  415.         if (tmp = *(int *)data)
  416.             fp->f_flag |= FNONBLOCK;
  417.         else
  418.             fp->f_flag &= ~FNONBLOCK;
  419.         error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p);
  420.         break;
  421.  
  422.     case FIOASYNC:
  423.         if (tmp = *(int *)data)
  424.             fp->f_flag |= FASYNC;
  425.         else
  426.             fp->f_flag &= ~FASYNC;
  427.         error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p);
  428.         break;
  429.  
  430.     case FIOSETOWN:
  431.         tmp = *(int *)data;
  432.         if (fp->f_type == DTYPE_SOCKET) {
  433.             ((struct socket *)fp->f_data)->so_pgid = tmp;
  434.             error = 0;
  435.             break;
  436.         }
  437.         if (tmp <= 0) {
  438.             tmp = -tmp;
  439.         } else {
  440.             struct proc *p1 = pfind(tmp);
  441.             if (p1 == 0) {
  442.                 error = ESRCH;
  443.                 break;
  444.             }
  445.             tmp = p1->p_pgrp->pg_id;
  446.         }
  447.         error = (*fp->f_ops->fo_ioctl)
  448.             (fp, (int)TIOCSPGRP, (caddr_t)&tmp, p);
  449.         break;
  450.  
  451.     case FIOGETOWN:
  452.         if (fp->f_type == DTYPE_SOCKET) {
  453.             error = 0;
  454.             *(int *)data = ((struct socket *)fp->f_data)->so_pgid;
  455.             break;
  456.         }
  457.         error = (*fp->f_ops->fo_ioctl)(fp, (int)TIOCGPGRP, data, p);
  458.         *(int *)data = -*(int *)data;
  459.         break;
  460.  
  461.     default:
  462.         error = (*fp->f_ops->fo_ioctl)(fp, com, data, p);
  463.         /*
  464.          * Copy any data to user, size was
  465.          * already set and checked above.
  466.          */
  467.         if (error == 0 && (com&IOC_OUT) && size)
  468.             error = copyout(data, uap->cmarg, (u_int)size);
  469.         break;
  470.     }
  471.     if (memp)
  472.         free(memp, M_IOCTLOPS);
  473.     return (error);
  474. }
  475.  
  476. int    selwait, nselcoll;
  477.  
  478. /*
  479.  * Select system call.
  480.  */
  481. select(p, uap, retval)
  482.     register struct proc *p;
  483.     register struct args {
  484.         int    nd;
  485.         fd_set    *in, *ou, *ex;
  486.         struct    timeval *tv;
  487.     } *uap;
  488.     int *retval;
  489. {
  490.     fd_set ibits[3], obits[3];
  491.     struct timeval atv;
  492.     int s, ncoll, ni, error = 0, timo;
  493.  
  494.     bzero((caddr_t)ibits, sizeof(ibits));
  495.     bzero((caddr_t)obits, sizeof(obits));
  496.     if (uap->nd > p->p_fd->fd_nfiles)
  497.         uap->nd = p->p_fd->fd_nfiles;    /* forgiving; slightly wrong */
  498.     ni = howmany(uap->nd, NFDBITS);
  499.  
  500. #define    getbits(name, x) \
  501.     if (uap->name) { \
  502.         error = copyin((caddr_t)uap->name, (caddr_t)&ibits[x], \
  503.             (unsigned)(ni * sizeof(fd_mask))); \
  504.         if (error) \
  505.             goto done; \
  506.     }
  507.     getbits(in, 0);
  508.     getbits(ou, 1);
  509.     getbits(ex, 2);
  510. #undef    getbits
  511.  
  512.     if (uap->tv) {
  513.         error = copyin((caddr_t)uap->tv, (caddr_t)&atv,
  514.             sizeof (atv));
  515.         if (error)
  516.             goto done;
  517.         if (itimerfix(&atv)) {
  518.             error = EINVAL;
  519.             goto done;
  520.         }
  521.         s = splhigh(); timevaladd(&atv, &time); splx(s);
  522.         timo = hzto(&atv);
  523.     } else
  524.         timo = 0;
  525. retry:
  526.     ncoll = nselcoll;
  527.     p->p_flag |= SSEL;
  528.     error = selscan(p, ibits, obits, uap->nd, retval);
  529.     if (error || *retval)
  530.         goto done;
  531.     s = splhigh();
  532.     /* this should be timercmp(&time, &atv, >=) */
  533.     if (uap->tv && (time.tv_sec > atv.tv_sec ||
  534.         time.tv_sec == atv.tv_sec && time.tv_usec >= atv.tv_usec)) {
  535.         splx(s);
  536.         goto done;
  537.     }
  538.     if ((p->p_flag & SSEL) == 0 || nselcoll != ncoll) {
  539.         splx(s);
  540.         goto retry;
  541.     }
  542.     p->p_flag &= ~SSEL;
  543.     error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo);
  544.     splx(s);
  545.     if (error == 0)
  546.         goto retry;
  547. done:
  548.     p->p_flag &= ~SSEL;
  549.     /* select is not restarted after signals... */
  550.     if (error == ERESTART)
  551.         error = EINTR;
  552.     if (error == EWOULDBLOCK)
  553.         error = 0;
  554. #define    putbits(name, x) \
  555.     if (uap->name) { \
  556.         int error2 = copyout((caddr_t)&obits[x], (caddr_t)uap->name, \
  557.             (unsigned)(ni * sizeof(fd_mask))); \
  558.         if (error2) \
  559.             error = error2; \
  560.     }
  561.     if (error == 0) {
  562.         putbits(in, 0);
  563.         putbits(ou, 1);
  564.         putbits(ex, 2);
  565. #undef putbits
  566.     }
  567.     return (error);
  568. }
  569.  
  570. selscan(p, ibits, obits, nfd, retval)
  571.     struct proc *p;
  572.     fd_set *ibits, *obits;
  573.     int nfd, *retval;
  574. {
  575.     register struct filedesc *fdp = p->p_fd;
  576.     register int which, i, j;
  577.     register fd_mask bits;
  578.     int flag;
  579.     struct file *fp;
  580.     int error = 0, n = 0;
  581.  
  582.     for (which = 0; which < 3; which++) {
  583.         switch (which) {
  584.  
  585.         case 0:
  586.             flag = FREAD; break;
  587.  
  588.         case 1:
  589.             flag = FWRITE; break;
  590.  
  591.         case 2:
  592.             flag = 0; break;
  593.         }
  594.         for (i = 0; i < nfd; i += NFDBITS) {
  595.             bits = ibits[which].fds_bits[i/NFDBITS];
  596.             while ((j = ffs(bits)) && i + --j < nfd) {
  597.                 bits &= ~(1 << j);
  598.                 fp = fdp->fd_ofiles[i + j];
  599.                 if (fp == NULL) {
  600.                     error = EBADF;
  601.                     break;
  602.                 }
  603.                 if ((*fp->f_ops->fo_select)(fp, flag, p)) {
  604.                     FD_SET(i + j, &obits[which]);
  605.                     n++;
  606.                 }
  607.             }
  608.         }
  609.     }
  610.     *retval = n;
  611.     return (error);
  612. }
  613.  
  614. /*ARGSUSED*/
  615. #ifdef __STDC__
  616. seltrue(dev_t dev, int which, struct proc *p)
  617. #else
  618. seltrue(dev, flag, p)
  619.     dev_t dev;
  620.     int flag;
  621.     struct proc *p;
  622. #endif
  623. {
  624.  
  625.     return (1);
  626. }
  627.  
  628. selwakeup(p, coll)
  629.     register struct proc *p;
  630.     int coll;
  631. {
  632.  
  633.     if (coll) {
  634.         nselcoll++;
  635.         wakeup((caddr_t)&selwait);
  636.     }
  637.     if (p) {
  638.         int s = splhigh();
  639.         if (p->p_wchan == (caddr_t)&selwait) {
  640.             if (p->p_stat == SSLEEP)
  641.                 setrun(p);
  642.             else
  643.                 unsleep(p);
  644.         } else if (p->p_flag & SSEL)
  645.             p->p_flag &= ~SSEL;
  646.         splx(s);
  647.     }
  648. }
  649.