sys_generic.c revision 1.46 1 /* $NetBSD: sys_generic.c,v 1.46 2000/03/17 00:01:48 darrenr Exp $ */
2
3 /*
4 * Copyright (c) 1982, 1986, 1989, 1993
5 * The Regents of the University of California. All rights reserved.
6 * (c) UNIX System Laboratories, Inc.
7 * All or some portions of this file are derived from material licensed
8 * to the University of California by American Telephone and Telegraph
9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
10 * the permission of UNIX System Laboratories, Inc.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the University of
23 * California, Berkeley and its contributors.
24 * 4. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 *
40 * @(#)sys_generic.c 8.9 (Berkeley) 2/14/95
41 */
42
43 #include "opt_ktrace.h"
44
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/filedesc.h>
48 #include <sys/ioctl.h>
49 #include <sys/file.h>
50 #include <sys/proc.h>
51 #include <sys/socketvar.h>
52 #include <sys/signalvar.h>
53 #include <sys/uio.h>
54 #include <sys/kernel.h>
55 #include <sys/stat.h>
56 #include <sys/malloc.h>
57 #include <sys/poll.h>
58 #ifdef KTRACE
59 #include <sys/ktrace.h>
60 #endif
61
62 #include <sys/mount.h>
63 #include <sys/syscallargs.h>
64
65 int selscan __P((struct proc *, fd_mask *, fd_mask *, int, register_t *));
66 int pollscan __P((struct proc *, struct pollfd *, int, register_t *));
67
68 /*
69 * Read system call.
70 */
71 /* ARGSUSED */
72 int
73 sys_read(p, v, retval)
74 struct proc *p;
75 void *v;
76 register_t *retval;
77 {
78 register struct sys_read_args /* {
79 syscallarg(int) fd;
80 syscallarg(void *) buf;
81 syscallarg(size_t) nbyte;
82 } */ *uap = v;
83 int fd = SCARG(uap, fd);
84 register struct file *fp;
85 register struct filedesc *fdp = p->p_fd;
86
87 if ((u_int)fd >= fdp->fd_nfiles ||
88 (fp = fdp->fd_ofiles[fd]) == NULL ||
89 (fp->f_iflags & FIF_WANTCLOSE) != 0 ||
90 (fp->f_flag & FREAD) == 0)
91 return (EBADF);
92
93 FILE_USE(fp);
94
95 /* dofileread() will unuse the descriptor for us */
96 return (dofileread(p, fd, fp, SCARG(uap, buf), SCARG(uap, nbyte),
97 &fp->f_offset, FOF_UPDATE_OFFSET, retval));
98 }
99
100 int
101 dofileread(p, fd, fp, buf, nbyte, offset, flags, retval)
102 struct proc *p;
103 int fd;
104 struct file *fp;
105 void *buf;
106 size_t nbyte;
107 off_t *offset;
108 int flags;
109 register_t *retval;
110 {
111 struct uio auio;
112 struct iovec aiov;
113 long cnt, error = 0;
114 #ifdef KTRACE
115 struct iovec ktriov;
116 #endif
117
118 aiov.iov_base = (caddr_t)buf;
119 aiov.iov_len = nbyte;
120 auio.uio_iov = &aiov;
121 auio.uio_iovcnt = 1;
122 auio.uio_resid = nbyte;
123 auio.uio_rw = UIO_READ;
124 auio.uio_segflg = UIO_USERSPACE;
125 auio.uio_procp = p;
126
127 /*
128 * Reads return ssize_t because -1 is returned on error. Therefore
129 * we must restrict the length to SSIZE_MAX to avoid garbage return
130 * values.
131 */
132 if (auio.uio_resid > SSIZE_MAX) {
133 error = EINVAL;
134 goto out;
135 }
136
137 #ifdef KTRACE
138 /*
139 * if tracing, save a copy of iovec
140 */
141 if (KTRPOINT(p, KTR_GENIO))
142 ktriov = aiov;
143 #endif
144 cnt = auio.uio_resid;
145 error = (*fp->f_ops->fo_read)(fp, offset, &auio, fp->f_cred, flags);
146 if (error)
147 if (auio.uio_resid != cnt && (error == ERESTART ||
148 error == EINTR || error == EWOULDBLOCK))
149 error = 0;
150 cnt -= auio.uio_resid;
151 #ifdef KTRACE
152 if (KTRPOINT(p, KTR_GENIO) && error == 0)
153 ktrgenio(p->p_tracep, fd, UIO_READ, &ktriov, cnt, error);
154 #endif
155 *retval = cnt;
156 out:
157 FILE_UNUSE(fp, p);
158 return (error);
159 }
160
161 /*
162 * Scatter read system call.
163 */
164 int
165 sys_readv(p, v, retval)
166 struct proc *p;
167 void *v;
168 register_t *retval;
169 {
170 register struct sys_readv_args /* {
171 syscallarg(int) fd;
172 syscallarg(const struct iovec *) iovp;
173 syscallarg(int) iovcnt;
174 } */ *uap = v;
175 int fd = SCARG(uap, fd);
176 register struct file *fp;
177 register struct filedesc *fdp = p->p_fd;
178
179 if ((u_int)fd >= fdp->fd_nfiles ||
180 (fp = fdp->fd_ofiles[fd]) == NULL ||
181 (fp->f_iflags & FIF_WANTCLOSE) != 0 ||
182 (fp->f_flag & FREAD) == 0)
183 return (EBADF);
184
185 FILE_USE(fp);
186
187 /* dofilereadv() will unuse the descriptor for us */
188 return (dofilereadv(p, fd, fp, SCARG(uap, iovp), SCARG(uap, iovcnt),
189 &fp->f_offset, FOF_UPDATE_OFFSET, retval));
190 }
191
192 int
193 dofilereadv(p, fd, fp, iovp, iovcnt, offset, flags, retval)
194 struct proc *p;
195 int fd;
196 struct file *fp;
197 const struct iovec *iovp;
198 int iovcnt;
199 off_t *offset;
200 int flags;
201 register_t *retval;
202 {
203 struct uio auio;
204 register struct iovec *iov;
205 struct iovec *needfree;
206 struct iovec aiov[UIO_SMALLIOV];
207 long i, cnt, error = 0;
208 u_int iovlen;
209 #ifdef KTRACE
210 struct iovec *ktriov = NULL;
211 #endif
212
213 /* note: can't use iovlen until iovcnt is validated */
214 iovlen = iovcnt * sizeof(struct iovec);
215 if ((u_int)iovcnt > UIO_SMALLIOV) {
216 if ((u_int)iovcnt > IOV_MAX) {
217 error = EINVAL;
218 goto out;
219 }
220 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
221 needfree = iov;
222 } else if ((u_int)iovcnt > 0) {
223 iov = aiov;
224 needfree = NULL;
225 } else {
226 error = EINVAL;
227 goto out;
228 }
229
230 auio.uio_iov = iov;
231 auio.uio_iovcnt = iovcnt;
232 auio.uio_rw = UIO_READ;
233 auio.uio_segflg = UIO_USERSPACE;
234 auio.uio_procp = p;
235 error = copyin(iovp, iov, iovlen);
236 if (error)
237 goto done;
238 auio.uio_resid = 0;
239 for (i = 0; i < iovcnt; i++) {
240 auio.uio_resid += iov->iov_len;
241 /*
242 * Reads return ssize_t because -1 is returned on error.
243 * Therefore we must restrict the length to SSIZE_MAX to
244 * avoid garbage return values.
245 */
246 if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
247 error = EINVAL;
248 goto done;
249 }
250 iov++;
251 }
252 #ifdef KTRACE
253 /*
254 * if tracing, save a copy of iovec
255 */
256 if (KTRPOINT(p, KTR_GENIO)) {
257 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
258 memcpy((caddr_t)ktriov, (caddr_t)auio.uio_iov, iovlen);
259 }
260 #endif
261 cnt = auio.uio_resid;
262 error = (*fp->f_ops->fo_read)(fp, offset, &auio, fp->f_cred, flags);
263 if (error)
264 if (auio.uio_resid != cnt && (error == ERESTART ||
265 error == EINTR || error == EWOULDBLOCK))
266 error = 0;
267 cnt -= auio.uio_resid;
268 #ifdef KTRACE
269 if (KTRPOINT(p, KTR_GENIO))
270 if (error == 0) {
271 ktrgenio(p->p_tracep, fd, UIO_READ, ktriov, cnt,
272 error);
273 FREE(ktriov, M_TEMP);
274 }
275 #endif
276 *retval = cnt;
277 done:
278 if (needfree)
279 FREE(needfree, M_IOV);
280 out:
281 FILE_UNUSE(fp, p);
282 return (error);
283 }
284
285 /*
286 * Write system call
287 */
288 int
289 sys_write(p, v, retval)
290 struct proc *p;
291 void *v;
292 register_t *retval;
293 {
294 register struct sys_write_args /* {
295 syscallarg(int) fd;
296 syscallarg(const void *) buf;
297 syscallarg(size_t) nbyte;
298 } */ *uap = v;
299 int fd = SCARG(uap, fd);
300 register struct file *fp;
301 register struct filedesc *fdp = p->p_fd;
302
303 if ((u_int)fd >= fdp->fd_nfiles ||
304 (fp = fdp->fd_ofiles[fd]) == NULL ||
305 (fp->f_iflags & FIF_WANTCLOSE) != 0 ||
306 (fp->f_flag & FWRITE) == 0)
307 return (EBADF);
308
309 FILE_USE(fp);
310
311 /* dofilewrite() will unuse the descriptor for us */
312 return (dofilewrite(p, fd, fp, SCARG(uap, buf), SCARG(uap, nbyte),
313 &fp->f_offset, FOF_UPDATE_OFFSET, retval));
314 }
315
316 int
317 dofilewrite(p, fd, fp, buf, nbyte, offset, flags, retval)
318 struct proc *p;
319 int fd;
320 struct file *fp;
321 const void *buf;
322 size_t nbyte;
323 off_t *offset;
324 int flags;
325 register_t *retval;
326 {
327 struct uio auio;
328 struct iovec aiov;
329 long cnt, error = 0;
330 #ifdef KTRACE
331 struct iovec ktriov;
332 #endif
333
334 aiov.iov_base = (caddr_t)buf; /* XXX kills const */
335 aiov.iov_len = nbyte;
336 auio.uio_iov = &aiov;
337 auio.uio_iovcnt = 1;
338 auio.uio_resid = nbyte;
339 auio.uio_rw = UIO_WRITE;
340 auio.uio_segflg = UIO_USERSPACE;
341 auio.uio_procp = p;
342
343 /*
344 * Writes return ssize_t because -1 is returned on error. Therefore
345 * we must restrict the length to SSIZE_MAX to avoid garbage return
346 * values.
347 */
348 if (auio.uio_resid > SSIZE_MAX) {
349 error = EINVAL;
350 goto out;
351 }
352
353 #ifdef KTRACE
354 /*
355 * if tracing, save a copy of iovec
356 */
357 if (KTRPOINT(p, KTR_GENIO))
358 ktriov = aiov;
359 #endif
360 cnt = auio.uio_resid;
361 error = (*fp->f_ops->fo_write)(fp, offset, &auio, fp->f_cred, flags);
362 if (error) {
363 if (auio.uio_resid != cnt && (error == ERESTART ||
364 error == EINTR || error == EWOULDBLOCK))
365 error = 0;
366 if (error == EPIPE)
367 psignal(p, SIGPIPE);
368 }
369 cnt -= auio.uio_resid;
370 #ifdef KTRACE
371 if (KTRPOINT(p, KTR_GENIO) && error == 0)
372 ktrgenio(p->p_tracep, fd, UIO_WRITE, &ktriov, cnt, error);
373 #endif
374 *retval = cnt;
375 out:
376 FILE_UNUSE(fp, p);
377 return (error);
378 }
379
380 /*
381 * Gather write system call
382 */
383 int
384 sys_writev(p, v, retval)
385 struct proc *p;
386 void *v;
387 register_t *retval;
388 {
389 register struct sys_writev_args /* {
390 syscallarg(int) fd;
391 syscallarg(const struct iovec *) iovp;
392 syscallarg(int) iovcnt;
393 } */ *uap = v;
394 int fd = SCARG(uap, fd);
395 register struct file *fp;
396 register struct filedesc *fdp = p->p_fd;
397
398 if ((u_int)fd >= fdp->fd_nfiles ||
399 (fp = fdp->fd_ofiles[fd]) == NULL ||
400 (fp->f_iflags & FIF_WANTCLOSE) != 0 ||
401 (fp->f_flag & FWRITE) == 0)
402 return (EBADF);
403
404 FILE_USE(fp);
405
406 /* dofilewritev() will unuse the descriptor for us */
407 return (dofilewritev(p, fd, fp, SCARG(uap, iovp), SCARG(uap, iovcnt),
408 &fp->f_offset, FOF_UPDATE_OFFSET, retval));
409 }
410
411 int
412 dofilewritev(p, fd, fp, iovp, iovcnt, offset, flags, retval)
413 struct proc *p;
414 int fd;
415 struct file *fp;
416 const struct iovec *iovp;
417 int iovcnt;
418 off_t *offset;
419 int flags;
420 register_t *retval;
421 {
422 struct uio auio;
423 register struct iovec *iov;
424 struct iovec *needfree;
425 struct iovec aiov[UIO_SMALLIOV];
426 long i, cnt, error = 0;
427 u_int iovlen;
428 #ifdef KTRACE
429 struct iovec *ktriov = NULL;
430 #endif
431
432 /* note: can't use iovlen until iovcnt is validated */
433 iovlen = iovcnt * sizeof(struct iovec);
434 if ((u_int)iovcnt > UIO_SMALLIOV) {
435 if ((u_int)iovcnt > IOV_MAX)
436 return (EINVAL);
437 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
438 needfree = iov;
439 } else if ((u_int)iovcnt > 0) {
440 iov = aiov;
441 needfree = NULL;
442 } else {
443 error = EINVAL;
444 goto out;
445 }
446
447 auio.uio_iov = iov;
448 auio.uio_iovcnt = iovcnt;
449 auio.uio_rw = UIO_WRITE;
450 auio.uio_segflg = UIO_USERSPACE;
451 auio.uio_procp = p;
452 error = copyin(iovp, iov, iovlen);
453 if (error)
454 goto done;
455 auio.uio_resid = 0;
456 for (i = 0; i < iovcnt; i++) {
457 auio.uio_resid += iov->iov_len;
458 /*
459 * Writes return ssize_t because -1 is returned on error.
460 * Therefore we must restrict the length to SSIZE_MAX to
461 * avoid garbage return values.
462 */
463 if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
464 error = EINVAL;
465 goto done;
466 }
467 iov++;
468 }
469 #ifdef KTRACE
470 /*
471 * if tracing, save a copy of iovec
472 */
473 if (KTRPOINT(p, KTR_GENIO)) {
474 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
475 memcpy((caddr_t)ktriov, (caddr_t)auio.uio_iov, iovlen);
476 }
477 #endif
478 cnt = auio.uio_resid;
479 error = (*fp->f_ops->fo_write)(fp, offset, &auio, fp->f_cred, flags);
480 if (error) {
481 if (auio.uio_resid != cnt && (error == ERESTART ||
482 error == EINTR || error == EWOULDBLOCK))
483 error = 0;
484 if (error == EPIPE)
485 psignal(p, SIGPIPE);
486 }
487 cnt -= auio.uio_resid;
488 #ifdef KTRACE
489 if (KTRPOINT(p, KTR_GENIO))
490 if (error == 0) {
491 ktrgenio(p->p_tracep, fd, UIO_WRITE, ktriov, cnt,
492 error);
493 FREE(ktriov, M_TEMP);
494 }
495 #endif
496 *retval = cnt;
497 done:
498 if (needfree)
499 FREE(needfree, M_IOV);
500 out:
501 FILE_UNUSE(fp, p);
502 return (error);
503 }
504
505 /*
506 * Ioctl system call
507 */
508 /* ARGSUSED */
509 int
510 sys_ioctl(p, v, retval)
511 struct proc *p;
512 void *v;
513 register_t *retval;
514 {
515 register struct sys_ioctl_args /* {
516 syscallarg(int) fd;
517 syscallarg(u_long) com;
518 syscallarg(caddr_t) data;
519 } */ *uap = v;
520 register struct file *fp;
521 register struct filedesc *fdp;
522 register u_long com;
523 register int error = 0;
524 register u_int size;
525 caddr_t data, memp;
526 int tmp;
527 #define STK_PARAMS 128
528 u_long stkbuf[STK_PARAMS/sizeof(u_long)];
529
530 fdp = p->p_fd;
531 if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
532 (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
533 (fp->f_iflags & FIF_WANTCLOSE) != 0)
534 return (EBADF);
535
536 FILE_USE(fp);
537
538 if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
539 error = EBADF;
540 goto out;
541 }
542
543 switch (com = SCARG(uap, com)) {
544 case FIONCLEX:
545 fdp->fd_ofileflags[SCARG(uap, fd)] &= ~UF_EXCLOSE;
546 goto out;
547
548 case FIOCLEX:
549 fdp->fd_ofileflags[SCARG(uap, fd)] |= UF_EXCLOSE;
550 goto out;
551 }
552
553 /*
554 * Interpret high order word to find amount of data to be
555 * copied to/from the user's address space.
556 */
557 size = IOCPARM_LEN(com);
558 if (size > IOCPARM_MAX) {
559 error = ENOTTY;
560 goto out;
561 }
562 memp = NULL;
563 if (size > sizeof(stkbuf)) {
564 memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK);
565 data = memp;
566 } else
567 data = (caddr_t)stkbuf;
568 if (com&IOC_IN) {
569 if (size) {
570 error = copyin(SCARG(uap, data), data, size);
571 if (error) {
572 if (memp)
573 free(memp, M_IOCTLOPS);
574 goto out;
575 }
576 } else
577 *(caddr_t *)data = SCARG(uap, data);
578 } else if ((com&IOC_OUT) && size)
579 /*
580 * Zero the buffer so the user always
581 * gets back something deterministic.
582 */
583 memset(data, 0, size);
584 else if (com&IOC_VOID)
585 *(caddr_t *)data = SCARG(uap, data);
586
587 switch (com) {
588
589 case FIONBIO:
590 if ((tmp = *(int *)data) != 0)
591 fp->f_flag |= FNONBLOCK;
592 else
593 fp->f_flag &= ~FNONBLOCK;
594 error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p);
595 break;
596
597 case FIOASYNC:
598 if ((tmp = *(int *)data) != 0)
599 fp->f_flag |= FASYNC;
600 else
601 fp->f_flag &= ~FASYNC;
602 error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p);
603 break;
604
605 case FIOSETOWN:
606 tmp = *(int *)data;
607 if (fp->f_type == DTYPE_SOCKET) {
608 ((struct socket *)fp->f_data)->so_pgid = tmp;
609 error = 0;
610 break;
611 }
612 if (tmp <= 0) {
613 tmp = -tmp;
614 } else {
615 struct proc *p1 = pfind(tmp);
616 if (p1 == 0) {
617 error = ESRCH;
618 break;
619 }
620 tmp = p1->p_pgrp->pg_id;
621 }
622 error = (*fp->f_ops->fo_ioctl)
623 (fp, TIOCSPGRP, (caddr_t)&tmp, p);
624 break;
625
626 case FIOGETOWN:
627 if (fp->f_type == DTYPE_SOCKET) {
628 error = 0;
629 *(int *)data = ((struct socket *)fp->f_data)->so_pgid;
630 break;
631 }
632 error = (*fp->f_ops->fo_ioctl)(fp, TIOCGPGRP, data, p);
633 *(int *)data = -*(int *)data;
634 break;
635
636 default:
637 error = (*fp->f_ops->fo_ioctl)(fp, com, data, p);
638 /*
639 * Copy any data to user, size was
640 * already set and checked above.
641 */
642 if (error == 0 && (com&IOC_OUT) && size)
643 error = copyout(data, SCARG(uap, data), size);
644 break;
645 }
646 if (memp)
647 free(memp, M_IOCTLOPS);
648 out:
649 FILE_UNUSE(fp, p);
650 return (error);
651 }
652
653 int selwait, nselcoll;
654
655 /*
656 * Select system call.
657 */
658 int
659 sys_select(p, v, retval)
660 register struct proc *p;
661 void *v;
662 register_t *retval;
663 {
664 register struct sys_select_args /* {
665 syscallarg(int) nd;
666 syscallarg(fd_set *) in;
667 syscallarg(fd_set *) ou;
668 syscallarg(fd_set *) ex;
669 syscallarg(struct timeval *) tv;
670 } */ *uap = v;
671 caddr_t bits;
672 char smallbits[howmany(FD_SETSIZE, NFDBITS) * sizeof(fd_mask) * 6];
673 struct timeval atv;
674 int s, ncoll, error = 0, timo;
675 size_t ni;
676
677 if (SCARG(uap, nd) < 0)
678 return (EINVAL);
679 if (SCARG(uap, nd) > p->p_fd->fd_nfiles) {
680 /* forgiving; slightly wrong */
681 SCARG(uap, nd) = p->p_fd->fd_nfiles;
682 }
683 ni = howmany(SCARG(uap, nd), NFDBITS) * sizeof(fd_mask);
684 if (ni * 6 > sizeof(smallbits))
685 bits = malloc(ni * 6, M_TEMP, M_WAITOK);
686 else
687 bits = smallbits;
688
689 #define getbits(name, x) \
690 if (SCARG(uap, name)) { \
691 error = copyin(SCARG(uap, name), bits + ni * x, ni); \
692 if (error) \
693 goto done; \
694 } else \
695 memset(bits + ni * x, 0, ni);
696 getbits(in, 0);
697 getbits(ou, 1);
698 getbits(ex, 2);
699 #undef getbits
700
701 if (SCARG(uap, tv)) {
702 error = copyin(SCARG(uap, tv), (caddr_t)&atv,
703 sizeof(atv));
704 if (error)
705 goto done;
706 if (itimerfix(&atv)) {
707 error = EINVAL;
708 goto done;
709 }
710 s = splclock();
711 timeradd(&atv, &time, &atv);
712 timo = hzto(&atv);
713 /*
714 * Avoid inadvertently sleeping forever.
715 */
716 if (timo == 0)
717 timo = 1;
718 splx(s);
719 } else
720 timo = 0;
721 retry:
722 ncoll = nselcoll;
723 p->p_flag |= P_SELECT;
724 error = selscan(p, (fd_mask *)(bits + ni * 0),
725 (fd_mask *)(bits + ni * 3), SCARG(uap, nd), retval);
726 if (error || *retval)
727 goto done;
728 s = splhigh();
729 if (timo && timercmp(&time, &atv, >=)) {
730 splx(s);
731 goto done;
732 }
733 if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
734 splx(s);
735 goto retry;
736 }
737 p->p_flag &= ~P_SELECT;
738 error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo);
739 splx(s);
740 if (error == 0)
741 goto retry;
742 done:
743 p->p_flag &= ~P_SELECT;
744 /* select is not restarted after signals... */
745 if (error == ERESTART)
746 error = EINTR;
747 if (error == EWOULDBLOCK)
748 error = 0;
749 if (error == 0) {
750 #define putbits(name, x) \
751 if (SCARG(uap, name)) { \
752 error = copyout(bits + ni * x, SCARG(uap, name), ni); \
753 if (error) \
754 goto out; \
755 }
756 putbits(in, 3);
757 putbits(ou, 4);
758 putbits(ex, 5);
759 #undef putbits
760 }
761 out:
762 if (ni * 6 > sizeof(smallbits))
763 free(bits, M_TEMP);
764 return (error);
765 }
766
767 int
768 selscan(p, ibitp, obitp, nfd, retval)
769 struct proc *p;
770 fd_mask *ibitp, *obitp;
771 int nfd;
772 register_t *retval;
773 {
774 register struct filedesc *fdp = p->p_fd;
775 register int msk, i, j, fd;
776 register fd_mask ibits, obits;
777 struct file *fp;
778 int n = 0;
779 static int flag[3] = { POLLRDNORM | POLLHUP | POLLERR,
780 POLLWRNORM | POLLHUP | POLLERR,
781 POLLRDBAND };
782
783 for (msk = 0; msk < 3; msk++) {
784 for (i = 0; i < nfd; i += NFDBITS) {
785 ibits = *ibitp++;
786 obits = 0;
787 while ((j = ffs(ibits)) && (fd = i + --j) < nfd) {
788 ibits &= ~(1 << j);
789 fp = fdp->fd_ofiles[fd];
790 if (fp == NULL ||
791 (fp->f_iflags & FIF_WANTCLOSE) != 0)
792 return (EBADF);
793 FILE_USE(fp);
794 if ((*fp->f_ops->fo_poll)(fp, flag[msk], p)) {
795 obits |= (1 << j);
796 n++;
797 }
798 FILE_UNUSE(fp, p);
799 }
800 *obitp++ = obits;
801 }
802 }
803 *retval = n;
804 return (0);
805 }
806
807 /*
808 * Poll system call.
809 */
810 int
811 sys_poll(p, v, retval)
812 register struct proc *p;
813 void *v;
814 register_t *retval;
815 {
816 register struct sys_poll_args /* {
817 syscallarg(struct pollfd *) fds;
818 syscallarg(u_int) nfds;
819 syscallarg(int) timeout;
820 } */ *uap = v;
821 caddr_t bits;
822 char smallbits[32 * sizeof(struct pollfd)];
823 struct timeval atv;
824 int s, ncoll, error = 0, timo;
825 size_t ni;
826
827 if (SCARG(uap, nfds) > p->p_fd->fd_nfiles) {
828 /* forgiving; slightly wrong */
829 SCARG(uap, nfds) = p->p_fd->fd_nfiles;
830 }
831 ni = SCARG(uap, nfds) * sizeof(struct pollfd);
832 if (ni > sizeof(smallbits))
833 bits = malloc(ni, M_TEMP, M_WAITOK);
834 else
835 bits = smallbits;
836
837 error = copyin(SCARG(uap, fds), bits, ni);
838 if (error)
839 goto done;
840
841 if (SCARG(uap, timeout) != INFTIM) {
842 atv.tv_sec = SCARG(uap, timeout) / 1000;
843 atv.tv_usec = (SCARG(uap, timeout) % 1000) * 1000;
844 if (itimerfix(&atv)) {
845 error = EINVAL;
846 goto done;
847 }
848 s = splclock();
849 timeradd(&atv, &time, &atv);
850 timo = hzto(&atv);
851 /*
852 * Avoid inadvertently sleeping forever.
853 */
854 if (timo == 0)
855 timo = 1;
856 splx(s);
857 } else
858 timo = 0;
859 retry:
860 ncoll = nselcoll;
861 p->p_flag |= P_SELECT;
862 error = pollscan(p, (struct pollfd *)bits, SCARG(uap, nfds), retval);
863 if (error || *retval)
864 goto done;
865 s = splhigh();
866 if (timo && timercmp(&time, &atv, >=)) {
867 splx(s);
868 goto done;
869 }
870 if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
871 splx(s);
872 goto retry;
873 }
874 p->p_flag &= ~P_SELECT;
875 error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo);
876 splx(s);
877 if (error == 0)
878 goto retry;
879 done:
880 p->p_flag &= ~P_SELECT;
881 /* poll is not restarted after signals... */
882 if (error == ERESTART)
883 error = EINTR;
884 if (error == EWOULDBLOCK)
885 error = 0;
886 if (error == 0) {
887 error = copyout(bits, SCARG(uap, fds), ni);
888 if (error)
889 goto out;
890 }
891 out:
892 if (ni > sizeof(smallbits))
893 free(bits, M_TEMP);
894 return (error);
895 }
896
897 int
898 pollscan(p, fds, nfd, retval)
899 struct proc *p;
900 struct pollfd *fds;
901 int nfd;
902 register_t *retval;
903 {
904 register struct filedesc *fdp = p->p_fd;
905 int i;
906 struct file *fp;
907 int n = 0;
908
909 for (i = 0; i < nfd; i++, fds++) {
910 if ((u_int)fds->fd >= fdp->fd_nfiles) {
911 fds->revents = POLLNVAL;
912 n++;
913 } else {
914 fp = fdp->fd_ofiles[fds->fd];
915 if (fp == NULL ||
916 (fp->f_iflags & FIF_WANTCLOSE) != 0) {
917 fds->revents = POLLNVAL;
918 n++;
919 } else {
920 FILE_USE(fp);
921 fds->revents = (*fp->f_ops->fo_poll)(fp,
922 fds->events | POLLERR | POLLHUP, p);
923 if (fds->revents != 0)
924 n++;
925 FILE_UNUSE(fp, p);
926 }
927 }
928 }
929 *retval = n;
930 return (0);
931 }
932
933 /*ARGSUSED*/
934 int
935 seltrue(dev, events, p)
936 dev_t dev;
937 int events;
938 struct proc *p;
939 {
940
941 return (events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
942 }
943
944 /*
945 * Record a select request.
946 */
947 void
948 selrecord(selector, sip)
949 struct proc *selector;
950 struct selinfo *sip;
951 {
952 struct proc *p;
953 pid_t mypid;
954
955 mypid = selector->p_pid;
956 if (sip->si_pid == mypid)
957 return;
958 if (sip->si_pid && (p = pfind(sip->si_pid)) &&
959 p->p_wchan == (caddr_t)&selwait)
960 sip->si_flags |= SI_COLL;
961 else
962 sip->si_pid = mypid;
963 }
964
965 /*
966 * Do a wakeup when a selectable event occurs.
967 */
968 void
969 selwakeup(sip)
970 register struct selinfo *sip;
971 {
972 register struct proc *p;
973 int s;
974
975 if (sip->si_pid == 0)
976 return;
977 if (sip->si_flags & SI_COLL) {
978 nselcoll++;
979 sip->si_flags &= ~SI_COLL;
980 wakeup((caddr_t)&selwait);
981 }
982 p = pfind(sip->si_pid);
983 sip->si_pid = 0;
984 if (p != NULL) {
985 s = splhigh();
986 if (p->p_wchan == (caddr_t)&selwait) {
987 if (p->p_stat == SSLEEP)
988 setrunnable(p);
989 else
990 unsleep(p);
991 } else if (p->p_flag & P_SELECT)
992 p->p_flag &= ~P_SELECT;
993 splx(s);
994 }
995 }
996