1 /* $Id: sys_generic.c,v 1.1.1.1 2006/09/14 01:59:08 root Exp $ */
2 /* $OpenBSD: sys_generic.c,v 1.20 1999/08/04 19:18:13 deraadt Exp $ */
3 /* $NetBSD: sys_generic.c,v 1.24 1996/03/29 00:25:32 cgd Exp $ */
6 * Copyright (c) 1996 Theo de Raadt
7 * Copyright (c) 1982, 1986, 1989, 1993
8 * The Regents of the University of California. All rights reserved.
9 * (c) UNIX System Laboratories, Inc.
10 * All or some portions of this file are derived from material licensed
11 * to the University of California by American Telephone and Telegraph
12 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
13 * the permission of UNIX System Laboratories, Inc.
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 * 3. All advertising materials mentioning features or use of this software
24 * must display the following acknowledgement:
25 * This product includes software developed by the University of
26 * California, Berkeley and its contributors.
27 * 4. Neither the name of the University nor the names of its contributors
28 * may be used to endorse or promote products derived from this software
29 * without specific prior written permission.
31 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
32 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
35 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
40 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 * @(#)sys_generic.c 8.5 (Berkeley) 1/21/94
46 #include <sys/param.h>
47 #include <sys/systm.h>
48 #include <sys/filedesc.h>
49 #include <sys/ioctl.h>
52 #include <sys/socketvar.h>
53 #include <sys/signalvar.h>
55 #include <sys/kernel.h>
57 #include <sys/malloc.h>
60 #include <sys/ktrace.h>
64 #include <sys/mount.h>
66 #include <sys/syscallargs.h>
68 int selscan
__P((struct proc
*, fd_set
*, fd_set
*, int, register_t
*));
69 int seltrue
__P((dev_t
, int, struct proc
*));
70 void pollscan
__P((struct proc
*, struct pollfd
*, int, register_t
*));
77 sys_read(p
, v
, retval
)
82 register struct sys_read_args
/* {
84 syscallarg(void *) buf;
85 syscallarg(size_t) nbyte;
87 register struct file
*fp
;
88 register struct filedesc
*fdp
= p
->p_fd
;
96 if (((u_int
)SCARG(uap
, fd
)) >= fdp
->fd_nfiles
||
97 (fp
= fdp
->fd_ofiles
[SCARG(uap
, fd
)]) == NULL
||
98 (fp
->f_flag
& FREAD
) == 0)
100 /* Don't allow nbyte to be larger than max return val */
101 if (SCARG(uap
, nbyte
) > SSIZE_MAX
)
103 aiov
.iov_base
= (caddr_t
)SCARG(uap
, buf
);
104 aiov
.iov_len
= SCARG(uap
, nbyte
);
105 auio
.uio_iov
= &aiov
;
107 auio
.uio_resid
= SCARG(uap
, nbyte
);
108 auio
.uio_rw
= UIO_READ
;
109 auio
.uio_segflg
= UIO_USERSPACE
;
113 * if tracing, save a copy of iovec
115 if (KTRPOINT(p
, KTR_GENIO
))
118 cnt
= SCARG(uap
, nbyte
);
119 error
= (*fp
->f_ops
->fo_read
)(fp
, &auio
, fp
->f_cred
);
121 if (auio
.uio_resid
!= cnt
&& (error
== ERESTART
||
122 error
== EINTR
|| error
== EWOULDBLOCK
))
124 cnt
-= auio
.uio_resid
;
126 if (KTRPOINT(p
, KTR_GENIO
) && error
== 0)
127 ktrgenio(p
->p_tracep
, SCARG(uap
, fd
), UIO_READ
, &ktriov
,
135 * Scatter read system call.
138 sys_readv(p
, v
, retval
)
143 register struct sys_readv_args
/* {
145 syscallarg(struct iovec *) iovp;
146 syscallarg(int) iovcnt;
148 register struct file
*fp
;
149 register struct filedesc
*fdp
= p
->p_fd
;
151 register struct iovec
*iov
;
152 struct iovec
*needfree
;
153 struct iovec aiov
[UIO_SMALLIOV
];
154 long i
, cnt
, error
= 0;
157 struct iovec
*ktriov
= NULL
;
160 if (((u_int
)SCARG(uap
, fd
)) >= fdp
->fd_nfiles
||
161 (fp
= fdp
->fd_ofiles
[SCARG(uap
, fd
)]) == NULL
||
162 (fp
->f_flag
& FREAD
) == 0)
164 if (SCARG(uap
, iovcnt
) <= 0)
166 /* note: can't use iovlen until iovcnt is validated */
167 iovlen
= SCARG(uap
, iovcnt
) * sizeof (struct iovec
);
168 if (SCARG(uap
, iovcnt
) > UIO_SMALLIOV
) {
169 if (SCARG(uap
, iovcnt
) > IOV_MAX
)
171 MALLOC(iov
, struct iovec
*, iovlen
, M_IOV
, M_WAITOK
);
178 auio
.uio_iovcnt
= SCARG(uap
, iovcnt
);
179 auio
.uio_rw
= UIO_READ
;
180 auio
.uio_segflg
= UIO_USERSPACE
;
182 error
= copyin((caddr_t
)SCARG(uap
, iovp
), (caddr_t
)iov
, iovlen
);
186 for (i
= 0; i
< SCARG(uap
, iovcnt
); i
++, iov
++) {
187 /* Don't allow sum > SSIZE_MAX */
188 if (iov
->iov_len
> SSIZE_MAX
||
189 (auio
.uio_resid
+= iov
->iov_len
) > SSIZE_MAX
) {
196 * if tracing, save a copy of iovec
198 if (KTRPOINT(p
, KTR_GENIO
)) {
199 MALLOC(ktriov
, struct iovec
*, iovlen
, M_TEMP
, M_WAITOK
);
200 bcopy((caddr_t
)auio
.uio_iov
, (caddr_t
)ktriov
, iovlen
);
203 cnt
= auio
.uio_resid
;
204 error
= (*fp
->f_ops
->fo_read
)(fp
, &auio
, fp
->f_cred
);
206 if (auio
.uio_resid
!= cnt
&& (error
== ERESTART
||
207 error
== EINTR
|| error
== EWOULDBLOCK
))
209 cnt
-= auio
.uio_resid
;
211 if (ktriov
!= NULL
) {
213 ktrgenio(p
->p_tracep
, SCARG(uap
, fd
), UIO_READ
, ktriov
,
215 FREE(ktriov
, M_TEMP
);
221 FREE(needfree
, M_IOV
);
229 sys_write(p
, v
, retval
)
234 register struct sys_write_args
/* {
236 syscallarg(void *) buf;
237 syscallarg(size_t) nbyte;
239 register struct file
*fp
;
240 register struct filedesc
*fdp
= p
->p_fd
;
248 if (((u_int
)SCARG(uap
, fd
)) >= fdp
->fd_nfiles
||
249 (fp
= fdp
->fd_ofiles
[SCARG(uap
, fd
)]) == NULL
||
250 (fp
->f_flag
& FWRITE
) == 0)
252 /* Don't allow nbyte to be larger than max return val */
253 if (SCARG(uap
, nbyte
) > SSIZE_MAX
)
255 aiov
.iov_base
= (caddr_t
)SCARG(uap
, buf
);
256 aiov
.iov_len
= SCARG(uap
, nbyte
);
257 auio
.uio_iov
= &aiov
;
259 auio
.uio_resid
= SCARG(uap
, nbyte
);
260 auio
.uio_rw
= UIO_WRITE
;
261 auio
.uio_segflg
= UIO_USERSPACE
;
265 * if tracing, save a copy of iovec
267 if (KTRPOINT(p
, KTR_GENIO
))
270 cnt
= SCARG(uap
, nbyte
);
271 error
= (*fp
->f_ops
->fo_write
)(fp
, &auio
, fp
->f_cred
);
273 if (auio
.uio_resid
!= cnt
&& (error
== ERESTART
||
274 error
== EINTR
|| error
== EWOULDBLOCK
))
279 cnt
-= auio
.uio_resid
;
281 if (KTRPOINT(p
, KTR_GENIO
) && error
== 0)
282 ktrgenio(p
->p_tracep
, SCARG(uap
, fd
), UIO_WRITE
,
283 &ktriov
, cnt
, error
);
290 * Gather write system call
293 sys_writev(p
, v
, retval
)
298 register struct sys_writev_args
/* {
300 syscallarg(struct iovec *) iovp;
301 syscallarg(int) iovcnt;
303 register struct file
*fp
;
304 register struct filedesc
*fdp
= p
->p_fd
;
306 register struct iovec
*iov
;
307 struct iovec
*needfree
;
308 struct iovec aiov
[UIO_SMALLIOV
];
309 long i
, cnt
, error
= 0;
312 struct iovec
*ktriov
= NULL
;
315 if (((u_int
)SCARG(uap
, fd
)) >= fdp
->fd_nfiles
||
316 (fp
= fdp
->fd_ofiles
[SCARG(uap
, fd
)]) == NULL
||
317 (fp
->f_flag
& FWRITE
) == 0)
319 if (SCARG(uap
, iovcnt
) <= 0)
321 /* note: can't use iovlen until iovcnt is validated */
322 iovlen
= SCARG(uap
, iovcnt
) * sizeof (struct iovec
);
323 if (SCARG(uap
, iovcnt
) > UIO_SMALLIOV
) {
324 if (SCARG(uap
, iovcnt
) > IOV_MAX
)
326 MALLOC(iov
, struct iovec
*, iovlen
, M_IOV
, M_WAITOK
);
333 auio
.uio_iovcnt
= SCARG(uap
, iovcnt
);
334 auio
.uio_rw
= UIO_WRITE
;
335 auio
.uio_segflg
= UIO_USERSPACE
;
337 error
= copyin((caddr_t
)SCARG(uap
, iovp
), (caddr_t
)iov
, iovlen
);
341 for (i
= 0; i
< SCARG(uap
, iovcnt
); i
++, iov
++) {
342 /* Don't allow sum > SSIZE_MAX */
343 if (iov
->iov_len
> SSIZE_MAX
||
344 (auio
.uio_resid
+= iov
->iov_len
) > SSIZE_MAX
) {
351 * if tracing, save a copy of iovec
353 if (KTRPOINT(p
, KTR_GENIO
)) {
354 MALLOC(ktriov
, struct iovec
*, iovlen
, M_TEMP
, M_WAITOK
);
355 bcopy((caddr_t
)auio
.uio_iov
, (caddr_t
)ktriov
, iovlen
);
358 cnt
= auio
.uio_resid
;
359 error
= (*fp
->f_ops
->fo_write
)(fp
, &auio
, fp
->f_cred
);
361 if (auio
.uio_resid
!= cnt
&& (error
== ERESTART
||
362 error
== EINTR
|| error
== EWOULDBLOCK
))
367 cnt
-= auio
.uio_resid
;
369 if (ktriov
!= NULL
) {
371 ktrgenio(p
->p_tracep
, SCARG(uap
, fd
), UIO_WRITE
,
373 FREE(ktriov
, M_TEMP
);
379 FREE(needfree
, M_IOV
);
388 sys_ioctl(p
, v
, retval
)
393 register struct sys_ioctl_args
/* {
395 syscallarg(u_long) com;
396 syscallarg(caddr_t) data;
398 register struct file
*fp
;
399 register struct filedesc
*fdp
;
405 #define STK_PARAMS 128
406 char stkbuf
[STK_PARAMS
];
409 if ((u_int
)SCARG(uap
, fd
) >= fdp
->fd_nfiles
||
410 (fp
= fdp
->fd_ofiles
[SCARG(uap
, fd
)]) == NULL
)
413 if ((fp
->f_flag
& (FREAD
| FWRITE
)) == 0)
416 switch (com
= SCARG(uap
, com
)) {
418 fdp
->fd_ofileflags
[SCARG(uap
, fd
)] &= ~UF_EXCLOSE
;
421 fdp
->fd_ofileflags
[SCARG(uap
, fd
)] |= UF_EXCLOSE
;
426 * Interpret high order word to find amount of data to be
427 * copied to/from the user's address space.
429 size
= IOCPARM_LEN(com
);
430 if (size
> IOCPARM_MAX
)
433 if (size
> sizeof (stkbuf
)) {
434 memp
= (caddr_t
)malloc((u_long
)size
, M_IOCTLOPS
, M_WAITOK
);
440 error
= copyin(SCARG(uap
, data
), data
, (u_int
)size
);
443 free(memp
, M_IOCTLOPS
);
447 *(caddr_t
*)data
= SCARG(uap
, data
);
448 } else if ((com
&IOC_OUT
) && size
)
450 * Zero the buffer so the user always
451 * gets back something deterministic.
454 else if (com
&IOC_VOID
)
455 *(caddr_t
*)data
= SCARG(uap
, data
);
460 if ((tmp
= *(int *)data
) != 0)
461 fp
->f_flag
|= FNONBLOCK
;
463 fp
->f_flag
&= ~FNONBLOCK
;
464 error
= (*fp
->f_ops
->fo_ioctl
)(fp
, FIONBIO
, (caddr_t
)&tmp
, p
);
468 if ((tmp
= *(int *)data
) != 0)
469 fp
->f_flag
|= FASYNC
;
471 fp
->f_flag
&= ~FASYNC
;
472 error
= (*fp
->f_ops
->fo_ioctl
)(fp
, FIOASYNC
, (caddr_t
)&tmp
, p
);
477 if (fp
->f_type
== DTYPE_SOCKET
) {
478 struct socket
*so
= (struct socket
*)fp
->f_data
;
481 #ifdef NOTUSE_BY_PMON
482 so
->so_siguid
= p
->p_cred
->p_ruid
;
483 so
->so_sigeuid
= p
->p_ucred
->cr_uid
;
494 #ifdef NOTUSED_BY_PMON
495 struct proc
*p1
= pfind(tmp
);
500 tmp
= p1
->p_pgrp
->pg_id
;
505 error
= (*fp
->f_ops
->fo_ioctl
)
506 (fp
, TIOCSPGRP
, (caddr_t
)&tmp
, p
);
510 if (fp
->f_type
== DTYPE_SOCKET
) {
512 *(int *)data
= ((struct socket
*)fp
->f_data
)->so_pgid
;
515 error
= (*fp
->f_ops
->fo_ioctl
)(fp
, TIOCGPGRP
, data
, p
);
516 *(int *)data
= -*(int *)data
;
520 error
= (*fp
->f_ops
->fo_ioctl
)(fp
, com
, data
, p
);
522 * Copy any data to user, size was
523 * already set and checked above.
525 if (error
== 0 && (com
&IOC_OUT
) && size
)
526 error
= copyout(data
, SCARG(uap
, data
), (u_int
)size
);
530 free(memp
, M_IOCTLOPS
);
534 int selwait
, nselcoll
;
537 * Select system call.
540 sys_select(p
, v
, retval
)
541 register struct proc
*p
;
545 register struct sys_select_args
/* {
547 syscallarg(fd_set *) in;
548 syscallarg(fd_set *) ou;
549 syscallarg(fd_set *) ex;
550 syscallarg(struct timeval *) tv;
552 fd_set bits
[6], *pibits
[3], *pobits
[3];
554 int s
, ncoll
, error
= 0, timo
;
557 if (SCARG(uap
, nd
) > p
->p_fd
->fd_nfiles
) {
558 /* forgiving; slightly wrong */
559 SCARG(uap
, nd
) = p
->p_fd
->fd_nfiles
;
561 ni
= howmany(SCARG(uap
, nd
), NFDBITS
) * sizeof(fd_mask
);
562 if (SCARG(uap
, nd
) > FD_SETSIZE
) {
565 if ((mbits
= malloc(ni
* 6, M_TEMP
, M_WAITOK
)) == NULL
) {
569 bzero(mbits
, ni
* 6);
570 pibits
[0] = (fd_set
*)&mbits
[ni
* 0];
571 pibits
[1] = (fd_set
*)&mbits
[ni
* 1];
572 pibits
[2] = (fd_set
*)&mbits
[ni
* 2];
573 pobits
[0] = (fd_set
*)&mbits
[ni
* 3];
574 pobits
[1] = (fd_set
*)&mbits
[ni
* 4];
575 pobits
[2] = (fd_set
*)&mbits
[ni
* 5];
577 bzero((caddr_t
)bits
, sizeof(bits
));
578 pibits
[0] = &bits
[0];
579 pibits
[1] = &bits
[1];
580 pibits
[2] = &bits
[2];
581 pobits
[0] = &bits
[3];
582 pobits
[1] = &bits
[4];
583 pobits
[2] = &bits
[5];
586 #define getbits(name, x) \
587 if (SCARG(uap, name) && (error = copyin((caddr_t)SCARG(uap, name), \
588 (caddr_t)pibits[x], ni))) \
595 if (SCARG(uap
, tv
)) {
596 error
= copyin((caddr_t
)SCARG(uap
, tv
), (caddr_t
)&atv
,
600 if (itimerfix(&atv
)) {
605 timeradd(&atv
, &time
, &atv
);
608 * Avoid inadvertently sleeping forever.
617 p
->p_flag
|= P_SELECT
;
618 error
= selscan(p
, pibits
[0], pobits
[0], SCARG(uap
, nd
), retval
);
619 if (error
|| *retval
)
622 /* this should be timercmp(&time, &atv, >=) */
623 if (SCARG(uap
, tv
) && (time
.tv_sec
> atv
.tv_sec
||
624 (time
.tv_sec
== atv
.tv_sec
&& time
.tv_usec
>= atv
.tv_usec
))) {
628 if ((p
->p_flag
& P_SELECT
) == 0 || nselcoll
!= ncoll
) {
632 p
->p_flag
&= ~P_SELECT
;
633 error
= tsleep((caddr_t
)&selwait
, PSOCK
| PCATCH
, "select", timo
);
638 p
->p_flag
&= ~P_SELECT
;
639 /* select is not restarted after signals... */
640 if (error
== ERESTART
)
642 if (error
== EWOULDBLOCK
)
644 #define putbits(name, x) \
645 if (SCARG(uap, name) && (error2 = copyout((caddr_t)pobits[x], \
646 (caddr_t)SCARG(uap, name), ni))) \
658 if (pibits
[0] != &bits
[0])
659 free(pibits
[0], M_TEMP
);
664 selscan(p
, ibits
, obits
, nfd
, retval
)
666 fd_set
*ibits
, *obits
;
670 caddr_t cibits
= (caddr_t
)ibits
, cobits
= (caddr_t
)obits
;
671 register struct filedesc
*fdp
= p
->p_fd
;
672 register int msk
, i
, j
, fd
;
673 register fd_mask bits
;
676 static int flag
[3] = { FREAD
, FWRITE
, 0 };
679 * if nfd > FD_SETSIZE then the fd_set's contain nfd bits (rounded
680 * up to the next byte) otherwise the fd_set's are normal sized.
683 if (nfd
> FD_SETSIZE
)
684 ni
= howmany(nfd
, NFDBITS
) * sizeof(fd_mask
);
686 for (msk
= 0; msk
< 3; msk
++) {
687 fd_set
*pibits
= (fd_set
*)&cibits
[msk
*ni
];
688 fd_set
*pobits
= (fd_set
*)&cobits
[msk
*ni
];
690 for (i
= 0; i
< nfd
; i
+= NFDBITS
) {
691 bits
= pibits
->fds_bits
[i
/NFDBITS
];
692 while ((j
= ffs(bits
)) && (fd
= i
+ --j
) < nfd
) {
694 fp
= fdp
->fd_ofiles
[fd
];
697 if ((*fp
->f_ops
->fo_select
)(fp
, flag
[msk
], p
)) {
710 seltrue(dev
, flag
, p
)
720 * Record a select request.
723 selrecord(selector
, sip
)
724 struct proc
*selector
;
730 mypid
= selector
->p_pid
;
731 if (sip
->si_selpid
== mypid
)
733 if (sip
->si_selpid
&& (p
= pfind(sip
->si_selpid
)) &&
734 p
->p_wchan
== (caddr_t
)&selwait
)
735 sip
->si_flags
|= SI_COLL
;
737 sip
->si_selpid
= mypid
;
741 * Do a wakeup when a selectable event occurs.
745 register struct selinfo
*sip
;
747 register struct proc
*p
;
750 if (sip
->si_selpid
== 0)
752 if (sip
->si_flags
& SI_COLL
) {
754 sip
->si_flags
&= ~SI_COLL
;
755 wakeup((caddr_t
)&selwait
);
757 p
= pfind(sip
->si_selpid
);
761 if (p
->p_wchan
== (caddr_t
)&selwait
) {
762 if (p
->p_stat
== SSLEEP
)
766 } else if (p
->p_flag
& P_SELECT
)
767 p
->p_flag
&= ~P_SELECT
;
773 pollscan(p
, pl
, nfd
, retval
)
779 register struct filedesc
*fdp
= p
->p_fd
;
783 static int flag
[3] = { FREAD
, FWRITE
, 0 };
784 static int pflag
[3] = { POLLIN
|POLLRDNORM
, POLLOUT
, POLLERR
};
787 * XXX: We need to implement the rest of the flags.
789 for (i
= 0; i
< nfd
; i
++) {
790 fp
= fdp
->fd_ofiles
[pl
[i
].fd
];
792 if (pl
[i
].events
& POLLNVAL
) {
793 pl
[i
].revents
|= POLLNVAL
;
798 for (x
= msk
= 0; msk
< 3; msk
++) {
799 if (pl
[i
].events
& pflag
[msk
]) {
800 if ((*fp
->f_ops
->fo_select
)(fp
, flag
[msk
], p
)) {
801 pl
[i
].revents
|= pflag
[msk
] &
814 * We are using the same mechanism as select only we encode/decode args
818 sys_poll(p
, v
, retval
)
819 register struct proc
*p
;
823 struct sys_poll_args
*uap
= v
;
825 struct pollfd pfds
[4], *pl
= pfds
;
826 int msec
= SCARG(uap
, timeout
);
828 int timo
, ncoll
, i
, s
, error
, error2
;
829 extern int nselcoll
, selwait
;
831 /* XXX constrain; This may not match standards */
832 if (SCARG(uap
, nfds
) > p
->p_fd
->fd_nfiles
)
833 SCARG(uap
, nfds
) = p
->p_fd
->fd_nfiles
;
834 sz
= sizeof(struct pollfd
) * SCARG(uap
, nfds
);
836 /* optimize for the default case, of a small nfds value */
837 if (sz
> sizeof(pfds
))
838 pl
= (struct pollfd
*) malloc(sz
, M_TEMP
, M_WAITOK
);
840 if ((error
= copyin(SCARG(uap
, fds
), pl
, sz
)) != 0)
843 for (i
= 0; i
< SCARG(uap
, nfds
); i
++)
847 atv
.tv_sec
= msec
/ 1000;
848 atv
.tv_usec
= (msec
- (atv
.tv_sec
* 1000)) * 1000;
850 if (itimerfix(&atv
)) {
855 timeradd(&atv
, &time
, &atv
);
858 * Avoid inadvertently sleeping forever.
868 p
->p_flag
|= P_SELECT
;
869 pollscan(p
, pl
, SCARG(uap
, nfds
), retval
);
873 if (timo
&& timercmp(&time
, &atv
, >=)) {
877 if ((p
->p_flag
& P_SELECT
) == 0 || nselcoll
!= ncoll
) {
881 p
->p_flag
&= ~P_SELECT
;
882 error
= tsleep((caddr_t
)&selwait
, PSOCK
| PCATCH
, "poll", timo
);
888 p
->p_flag
&= ~P_SELECT
;
889 /* poll is not restarted after signals... */
890 if (error
== ERESTART
)
892 if (error
== EWOULDBLOCK
)
894 if ((error2
= copyout(pl
, SCARG(uap
, fds
), sz
)) != 0)
898 free((char *) pl
, M_TEMP
);