sys_generic.c revision 1.40 1 /* $NetBSD: sys_generic.c,v 1.40 1998/07/28 17:58:29 thorpej 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_flag & FREAD) == 0)
90 return (EBADF);
91
92 return (dofileread(p, fd, fp, SCARG(uap, buf), SCARG(uap, nbyte),
93 &fp->f_offset, FOF_UPDATE_OFFSET, retval));
94 }
95
96 int
97 dofileread(p, fd, fp, buf, nbyte, offset, flags, retval)
98 struct proc *p;
99 int fd;
100 struct file *fp;
101 void *buf;
102 size_t nbyte;
103 off_t *offset;
104 int flags;
105 register_t *retval;
106 {
107 struct uio auio;
108 struct iovec aiov;
109 long cnt, error = 0;
110 #ifdef KTRACE
111 struct iovec ktriov;
112 #endif
113
114 aiov.iov_base = (caddr_t)buf;
115 aiov.iov_len = nbyte;
116 auio.uio_iov = &aiov;
117 auio.uio_iovcnt = 1;
118 auio.uio_resid = nbyte;
119 auio.uio_rw = UIO_READ;
120 auio.uio_segflg = UIO_USERSPACE;
121 auio.uio_procp = p;
122
123 /*
124 * Reads return ssize_t because -1 is returned on error. Therefore
125 * we must restrict the length to SSIZE_MAX to avoid garbage return
126 * values.
127 */
128 if (auio.uio_resid > SSIZE_MAX)
129 return (EINVAL);
130
131 #ifdef KTRACE
132 /*
133 * if tracing, save a copy of iovec
134 */
135 if (KTRPOINT(p, KTR_GENIO))
136 ktriov = aiov;
137 #endif
138 cnt = auio.uio_resid;
139 error = (*fp->f_ops->fo_read)(fp, offset, &auio, fp->f_cred, flags);
140 if (error)
141 if (auio.uio_resid != cnt && (error == ERESTART ||
142 error == EINTR || error == EWOULDBLOCK))
143 error = 0;
144 cnt -= auio.uio_resid;
145 #ifdef KTRACE
146 if (KTRPOINT(p, KTR_GENIO) && error == 0)
147 ktrgenio(p->p_tracep, fd, UIO_READ, &ktriov, cnt, error);
148 #endif
149 *retval = cnt;
150 return (error);
151 }
152
153 /*
154 * Scatter read system call.
155 */
156 int
157 sys_readv(p, v, retval)
158 struct proc *p;
159 void *v;
160 register_t *retval;
161 {
162 register struct sys_readv_args /* {
163 syscallarg(int) fd;
164 syscallarg(const struct iovec *) iovp;
165 syscallarg(int) iovcnt;
166 } */ *uap = v;
167 int fd = SCARG(uap, fd);
168 register struct file *fp;
169 register struct filedesc *fdp = p->p_fd;
170
171 if ((u_int)fd >= fdp->fd_nfiles ||
172 (fp = fdp->fd_ofiles[fd]) == NULL ||
173 (fp->f_flag & FREAD) == 0)
174 return (EBADF);
175
176 return (dofilereadv(p, fd, fp, SCARG(uap, iovp), SCARG(uap, iovcnt),
177 &fp->f_offset, FOF_UPDATE_OFFSET, retval));
178 }
179
180 int
181 dofilereadv(p, fd, fp, iovp, iovcnt, offset, flags, retval)
182 struct proc *p;
183 int fd;
184 struct file *fp;
185 const struct iovec *iovp;
186 int iovcnt;
187 off_t *offset;
188 int flags;
189 register_t *retval;
190 {
191 struct uio auio;
192 register struct iovec *iov;
193 struct iovec *needfree;
194 struct iovec aiov[UIO_SMALLIOV];
195 long i, cnt, error = 0;
196 u_int iovlen;
197 #ifdef KTRACE
198 struct iovec *ktriov = NULL;
199 #endif
200
201 /* note: can't use iovlen until iovcnt is validated */
202 iovlen = iovcnt * sizeof (struct iovec);
203 if ((u_int)iovcnt > UIO_SMALLIOV) {
204 if ((u_int)iovcnt > UIO_MAXIOV)
205 return (EINVAL);
206 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
207 needfree = iov;
208 } else {
209 iov = aiov;
210 needfree = NULL;
211 }
212 auio.uio_iov = iov;
213 auio.uio_iovcnt = iovcnt;
214 auio.uio_rw = UIO_READ;
215 auio.uio_segflg = UIO_USERSPACE;
216 auio.uio_procp = p;
217 error = copyin(iovp, iov, iovlen);
218 if (error)
219 goto done;
220 auio.uio_resid = 0;
221 for (i = 0; i < iovcnt; i++) {
222 auio.uio_resid += iov->iov_len;
223 /*
224 * Reads return ssize_t because -1 is returned on error.
225 * Therefore we must restrict the length to SSIZE_MAX to
226 * avoid garbage return values.
227 */
228 if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
229 error = EINVAL;
230 goto done;
231 }
232 iov++;
233 }
234 #ifdef KTRACE
235 /*
236 * if tracing, save a copy of iovec
237 */
238 if (KTRPOINT(p, KTR_GENIO)) {
239 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
240 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
241 }
242 #endif
243 cnt = auio.uio_resid;
244 error = (*fp->f_ops->fo_read)(fp, offset, &auio, fp->f_cred, flags);
245 if (error)
246 if (auio.uio_resid != cnt && (error == ERESTART ||
247 error == EINTR || error == EWOULDBLOCK))
248 error = 0;
249 cnt -= auio.uio_resid;
250 #ifdef KTRACE
251 if (KTRPOINT(p, KTR_GENIO))
252 if (error == 0) {
253 ktrgenio(p->p_tracep, fd, UIO_READ, ktriov, cnt,
254 error);
255 FREE(ktriov, M_TEMP);
256 }
257 #endif
258 *retval = cnt;
259 done:
260 if (needfree)
261 FREE(needfree, M_IOV);
262 return (error);
263 }
264
265 /*
266 * Write system call
267 */
268 int
269 sys_write(p, v, retval)
270 struct proc *p;
271 void *v;
272 register_t *retval;
273 {
274 register struct sys_write_args /* {
275 syscallarg(int) fd;
276 syscallarg(const void *) buf;
277 syscallarg(size_t) nbyte;
278 } */ *uap = v;
279 int fd = SCARG(uap, fd);
280 register struct file *fp;
281 register struct filedesc *fdp = p->p_fd;
282
283 if ((u_int)fd >= fdp->fd_nfiles ||
284 (fp = fdp->fd_ofiles[fd]) == NULL ||
285 (fp->f_flag & FWRITE) == 0)
286 return (EBADF);
287
288 return (dofilewrite(p, fd, fp, SCARG(uap, buf), SCARG(uap, nbyte),
289 &fp->f_offset, FOF_UPDATE_OFFSET, retval));
290 }
291
292 int
293 dofilewrite(p, fd, fp, buf, nbyte, offset, flags, retval)
294 struct proc *p;
295 int fd;
296 struct file *fp;
297 const void *buf;
298 size_t nbyte;
299 off_t *offset;
300 int flags;
301 register_t *retval;
302 {
303 struct uio auio;
304 struct iovec aiov;
305 long cnt, error = 0;
306 #ifdef KTRACE
307 struct iovec ktriov;
308 #endif
309
310 aiov.iov_base = (caddr_t)buf; /* XXX kills const */
311 aiov.iov_len = nbyte;
312 auio.uio_iov = &aiov;
313 auio.uio_iovcnt = 1;
314 auio.uio_resid = nbyte;
315 auio.uio_rw = UIO_WRITE;
316 auio.uio_segflg = UIO_USERSPACE;
317 auio.uio_procp = p;
318
319 /*
320 * Writes return ssize_t because -1 is returned on error. Therefore
321 * we must restrict the length to SSIZE_MAX to avoid garbage return
322 * values.
323 */
324 if (auio.uio_resid > SSIZE_MAX)
325 return (EINVAL);
326
327 #ifdef KTRACE
328 /*
329 * if tracing, save a copy of iovec
330 */
331 if (KTRPOINT(p, KTR_GENIO))
332 ktriov = aiov;
333 #endif
334 cnt = auio.uio_resid;
335 error = (*fp->f_ops->fo_write)(fp, offset, &auio, fp->f_cred, flags);
336 if (error) {
337 if (auio.uio_resid != cnt && (error == ERESTART ||
338 error == EINTR || error == EWOULDBLOCK))
339 error = 0;
340 if (error == EPIPE)
341 psignal(p, SIGPIPE);
342 }
343 cnt -= auio.uio_resid;
344 #ifdef KTRACE
345 if (KTRPOINT(p, KTR_GENIO) && error == 0)
346 ktrgenio(p->p_tracep, fd, UIO_WRITE, &ktriov, cnt, error);
347 #endif
348 *retval = cnt;
349 return (error);
350 }
351
352 /*
353 * Gather write system call
354 */
355 int
356 sys_writev(p, v, retval)
357 struct proc *p;
358 void *v;
359 register_t *retval;
360 {
361 register struct sys_writev_args /* {
362 syscallarg(int) fd;
363 syscallarg(const struct iovec *) iovp;
364 syscallarg(int) iovcnt;
365 } */ *uap = v;
366 int fd = SCARG(uap, fd);
367 register struct file *fp;
368 register struct filedesc *fdp = p->p_fd;
369
370 if ((u_int)fd >= fdp->fd_nfiles ||
371 (fp = fdp->fd_ofiles[fd]) == NULL ||
372 (fp->f_flag & FWRITE) == 0)
373 return (EBADF);
374
375 return (dofilewritev(p, fd, fp, SCARG(uap, iovp), SCARG(uap, iovcnt),
376 &fp->f_offset, FOF_UPDATE_OFFSET, retval));
377 }
378
379 int
380 dofilewritev(p, fd, fp, iovp, iovcnt, offset, flags, retval)
381 struct proc *p;
382 int fd;
383 struct file *fp;
384 const struct iovec *iovp;
385 int iovcnt;
386 off_t *offset;
387 int flags;
388 register_t *retval;
389 {
390 struct uio auio;
391 register struct iovec *iov;
392 struct iovec *needfree;
393 struct iovec aiov[UIO_SMALLIOV];
394 long i, cnt, error = 0;
395 u_int iovlen;
396 #ifdef KTRACE
397 struct iovec *ktriov = NULL;
398 #endif
399
400 /* note: can't use iovlen until iovcnt is validated */
401 iovlen = iovcnt * sizeof (struct iovec);
402 if ((u_int)iovcnt > UIO_SMALLIOV) {
403 if ((u_int)iovcnt > UIO_MAXIOV)
404 return (EINVAL);
405 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
406 needfree = iov;
407 } else {
408 iov = aiov;
409 needfree = NULL;
410 }
411 auio.uio_iov = iov;
412 auio.uio_iovcnt = iovcnt;
413 auio.uio_rw = UIO_WRITE;
414 auio.uio_segflg = UIO_USERSPACE;
415 auio.uio_procp = p;
416 error = copyin(iovp, iov, iovlen);
417 if (error)
418 goto done;
419 auio.uio_resid = 0;
420 for (i = 0; i < iovcnt; i++) {
421 auio.uio_resid += iov->iov_len;
422 /*
423 * Writes return ssize_t because -1 is returned on error.
424 * Therefore we must restrict the length to SSIZE_MAX to
425 * avoid garbage return values.
426 */
427 if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
428 error = EINVAL;
429 goto done;
430 }
431 iov++;
432 }
433 #ifdef KTRACE
434 /*
435 * if tracing, save a copy of iovec
436 */
437 if (KTRPOINT(p, KTR_GENIO)) {
438 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
439 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
440 }
441 #endif
442 cnt = auio.uio_resid;
443 error = (*fp->f_ops->fo_write)(fp, offset, &auio, fp->f_cred, flags);
444 if (error) {
445 if (auio.uio_resid != cnt && (error == ERESTART ||
446 error == EINTR || error == EWOULDBLOCK))
447 error = 0;
448 if (error == EPIPE)
449 psignal(p, SIGPIPE);
450 }
451 cnt -= auio.uio_resid;
452 #ifdef KTRACE
453 if (KTRPOINT(p, KTR_GENIO))
454 if (error == 0) {
455 ktrgenio(p->p_tracep, fd, UIO_WRITE, ktriov, cnt,
456 error);
457 FREE(ktriov, M_TEMP);
458 }
459 #endif
460 *retval = cnt;
461 done:
462 if (needfree)
463 FREE(needfree, M_IOV);
464 return (error);
465 }
466
467 /*
468 * Ioctl system call
469 */
470 /* ARGSUSED */
471 int
472 sys_ioctl(p, v, retval)
473 struct proc *p;
474 void *v;
475 register_t *retval;
476 {
477 register struct sys_ioctl_args /* {
478 syscallarg(int) fd;
479 syscallarg(u_long) com;
480 syscallarg(caddr_t) data;
481 } */ *uap = v;
482 register struct file *fp;
483 register struct filedesc *fdp;
484 register u_long com;
485 register int error;
486 register u_int size;
487 caddr_t data, memp;
488 int tmp;
489 #define STK_PARAMS 128
490 char stkbuf[STK_PARAMS];
491
492 fdp = p->p_fd;
493 if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
494 (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
495 return (EBADF);
496
497 if ((fp->f_flag & (FREAD | FWRITE)) == 0)
498 return (EBADF);
499
500 switch (com = SCARG(uap, com)) {
501 case FIONCLEX:
502 fdp->fd_ofileflags[SCARG(uap, fd)] &= ~UF_EXCLOSE;
503 return (0);
504 case FIOCLEX:
505 fdp->fd_ofileflags[SCARG(uap, fd)] |= UF_EXCLOSE;
506 return (0);
507 }
508
509 /*
510 * Interpret high order word to find amount of data to be
511 * copied to/from the user's address space.
512 */
513 size = IOCPARM_LEN(com);
514 if (size > IOCPARM_MAX)
515 return (ENOTTY);
516 memp = NULL;
517 if (size > sizeof (stkbuf)) {
518 memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK);
519 data = memp;
520 } else
521 data = stkbuf;
522 if (com&IOC_IN) {
523 if (size) {
524 error = copyin(SCARG(uap, data), data, size);
525 if (error) {
526 if (memp)
527 free(memp, M_IOCTLOPS);
528 return (error);
529 }
530 } else
531 *(caddr_t *)data = SCARG(uap, data);
532 } else if ((com&IOC_OUT) && size)
533 /*
534 * Zero the buffer so the user always
535 * gets back something deterministic.
536 */
537 bzero(data, size);
538 else if (com&IOC_VOID)
539 *(caddr_t *)data = SCARG(uap, data);
540
541 switch (com) {
542
543 case FIONBIO:
544 if ((tmp = *(int *)data) != 0)
545 fp->f_flag |= FNONBLOCK;
546 else
547 fp->f_flag &= ~FNONBLOCK;
548 error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p);
549 break;
550
551 case FIOASYNC:
552 if ((tmp = *(int *)data) != 0)
553 fp->f_flag |= FASYNC;
554 else
555 fp->f_flag &= ~FASYNC;
556 error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p);
557 break;
558
559 case FIOSETOWN:
560 tmp = *(int *)data;
561 if (fp->f_type == DTYPE_SOCKET) {
562 ((struct socket *)fp->f_data)->so_pgid = tmp;
563 error = 0;
564 break;
565 }
566 if (tmp <= 0) {
567 tmp = -tmp;
568 } else {
569 struct proc *p1 = pfind(tmp);
570 if (p1 == 0) {
571 error = ESRCH;
572 break;
573 }
574 tmp = p1->p_pgrp->pg_id;
575 }
576 error = (*fp->f_ops->fo_ioctl)
577 (fp, TIOCSPGRP, (caddr_t)&tmp, p);
578 break;
579
580 case FIOGETOWN:
581 if (fp->f_type == DTYPE_SOCKET) {
582 error = 0;
583 *(int *)data = ((struct socket *)fp->f_data)->so_pgid;
584 break;
585 }
586 error = (*fp->f_ops->fo_ioctl)(fp, TIOCGPGRP, data, p);
587 *(int *)data = -*(int *)data;
588 break;
589
590 default:
591 error = (*fp->f_ops->fo_ioctl)(fp, com, data, p);
592 /*
593 * Copy any data to user, size was
594 * already set and checked above.
595 */
596 if (error == 0 && (com&IOC_OUT) && size)
597 error = copyout(data, SCARG(uap, data), size);
598 break;
599 }
600 if (memp)
601 free(memp, M_IOCTLOPS);
602 return (error);
603 }
604
605 int selwait, nselcoll;
606
607 /*
608 * Select system call.
609 */
610 int
611 sys_select(p, v, retval)
612 register struct proc *p;
613 void *v;
614 register_t *retval;
615 {
616 register struct sys_select_args /* {
617 syscallarg(int) nd;
618 syscallarg(fd_set *) in;
619 syscallarg(fd_set *) ou;
620 syscallarg(fd_set *) ex;
621 syscallarg(struct timeval *) tv;
622 } */ *uap = v;
623 caddr_t bits;
624 char smallbits[howmany(FD_SETSIZE, NFDBITS) * sizeof(fd_mask) * 6];
625 struct timeval atv;
626 int s, ncoll, error = 0, timo;
627 size_t ni;
628
629 if (SCARG(uap, nd) < 0)
630 return (EINVAL);
631 if (SCARG(uap, nd) > p->p_fd->fd_nfiles) {
632 /* forgiving; slightly wrong */
633 SCARG(uap, nd) = p->p_fd->fd_nfiles;
634 }
635 ni = howmany(SCARG(uap, nd), NFDBITS) * sizeof(fd_mask);
636 if (ni * 6 > sizeof(smallbits))
637 bits = malloc(ni * 6, M_TEMP, M_WAITOK);
638 else
639 bits = smallbits;
640
641 #define getbits(name, x) \
642 if (SCARG(uap, name)) { \
643 error = copyin(SCARG(uap, name), bits + ni * x, ni); \
644 if (error) \
645 goto done; \
646 } else \
647 bzero(bits + ni * x, ni);
648 getbits(in, 0);
649 getbits(ou, 1);
650 getbits(ex, 2);
651 #undef getbits
652
653 if (SCARG(uap, tv)) {
654 error = copyin(SCARG(uap, tv), (caddr_t)&atv,
655 sizeof (atv));
656 if (error)
657 goto done;
658 if (itimerfix(&atv)) {
659 error = EINVAL;
660 goto done;
661 }
662 s = splclock();
663 timeradd(&atv, &time, &atv);
664 timo = hzto(&atv);
665 /*
666 * Avoid inadvertently sleeping forever.
667 */
668 if (timo == 0)
669 timo = 1;
670 splx(s);
671 } else
672 timo = 0;
673 retry:
674 ncoll = nselcoll;
675 p->p_flag |= P_SELECT;
676 error = selscan(p, (fd_mask *)(bits + ni * 0),
677 (fd_mask *)(bits + ni * 3), SCARG(uap, nd), retval);
678 if (error || *retval)
679 goto done;
680 s = splhigh();
681 if (timo && timercmp(&time, &atv, >=)) {
682 splx(s);
683 goto done;
684 }
685 if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
686 splx(s);
687 goto retry;
688 }
689 p->p_flag &= ~P_SELECT;
690 error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo);
691 splx(s);
692 if (error == 0)
693 goto retry;
694 done:
695 p->p_flag &= ~P_SELECT;
696 /* select is not restarted after signals... */
697 if (error == ERESTART)
698 error = EINTR;
699 if (error == EWOULDBLOCK)
700 error = 0;
701 if (error == 0) {
702 #define putbits(name, x) \
703 if (SCARG(uap, name)) { \
704 error = copyout(bits + ni * x, SCARG(uap, name), ni); \
705 if (error) \
706 goto out; \
707 }
708 putbits(in, 3);
709 putbits(ou, 4);
710 putbits(ex, 5);
711 #undef putbits
712 }
713 out:
714 if (ni * 6 > sizeof(smallbits))
715 free(bits, M_TEMP);
716 return (error);
717 }
718
719 int
720 selscan(p, ibitp, obitp, nfd, retval)
721 struct proc *p;
722 fd_mask *ibitp, *obitp;
723 int nfd;
724 register_t *retval;
725 {
726 register struct filedesc *fdp = p->p_fd;
727 register int msk, i, j, fd;
728 register fd_mask ibits, obits;
729 struct file *fp;
730 int n = 0;
731 static int flag[3] = { POLLRDNORM | POLLHUP | POLLERR,
732 POLLWRNORM | POLLHUP | POLLERR,
733 POLLRDBAND };
734
735 for (msk = 0; msk < 3; msk++) {
736 for (i = 0; i < nfd; i += NFDBITS) {
737 ibits = *ibitp++;
738 obits = 0;
739 while ((j = ffs(ibits)) && (fd = i + --j) < nfd) {
740 ibits &= ~(1 << j);
741 fp = fdp->fd_ofiles[fd];
742 if (fp == NULL)
743 return (EBADF);
744 if ((*fp->f_ops->fo_poll)(fp, flag[msk], p)) {
745 obits |= (1 << j);
746 n++;
747 }
748 }
749 *obitp++ = obits;
750 }
751 }
752 *retval = n;
753 return (0);
754 }
755
756 /*
757 * Poll system call.
758 */
759 int
760 sys_poll(p, v, retval)
761 register struct proc *p;
762 void *v;
763 register_t *retval;
764 {
765 register struct sys_poll_args /* {
766 syscallarg(struct pollfd *) fds;
767 syscallarg(u_int) nfds;
768 syscallarg(int) timeout;
769 } */ *uap = v;
770 caddr_t bits;
771 char smallbits[32 * sizeof(struct pollfd)];
772 struct timeval atv;
773 int s, ncoll, error = 0, timo;
774 size_t ni;
775
776 if (SCARG(uap, nfds) > p->p_fd->fd_nfiles) {
777 /* forgiving; slightly wrong */
778 SCARG(uap, nfds) = p->p_fd->fd_nfiles;
779 }
780 ni = SCARG(uap, nfds) * sizeof(struct pollfd);
781 if (ni > sizeof(smallbits))
782 bits = malloc(ni, M_TEMP, M_WAITOK);
783 else
784 bits = smallbits;
785
786 error = copyin(SCARG(uap, fds), bits, ni);
787 if (error)
788 goto done;
789
790 if (SCARG(uap, timeout) != INFTIM) {
791 atv.tv_sec = SCARG(uap, timeout) / 1000;
792 atv.tv_usec = (SCARG(uap, timeout) % 1000) * 1000;
793 if (itimerfix(&atv)) {
794 error = EINVAL;
795 goto done;
796 }
797 s = splclock();
798 timeradd(&atv, &time, &atv);
799 timo = hzto(&atv);
800 /*
801 * Avoid inadvertently sleeping forever.
802 */
803 if (timo == 0)
804 timo = 1;
805 splx(s);
806 } else
807 timo = 0;
808 retry:
809 ncoll = nselcoll;
810 p->p_flag |= P_SELECT;
811 error = pollscan(p, (struct pollfd *)bits, SCARG(uap, nfds), retval);
812 if (error || *retval)
813 goto done;
814 s = splhigh();
815 if (timo && timercmp(&time, &atv, >=)) {
816 splx(s);
817 goto done;
818 }
819 if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
820 splx(s);
821 goto retry;
822 }
823 p->p_flag &= ~P_SELECT;
824 error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo);
825 splx(s);
826 if (error == 0)
827 goto retry;
828 done:
829 p->p_flag &= ~P_SELECT;
830 /* poll is not restarted after signals... */
831 if (error == ERESTART)
832 error = EINTR;
833 if (error == EWOULDBLOCK)
834 error = 0;
835 if (error == 0) {
836 error = copyout(bits, SCARG(uap, fds), ni);
837 if (error)
838 goto out;
839 }
840 out:
841 if (ni > sizeof(smallbits))
842 free(bits, M_TEMP);
843 return (error);
844 }
845
846 int
847 pollscan(p, fds, nfd, retval)
848 struct proc *p;
849 struct pollfd *fds;
850 int nfd;
851 register_t *retval;
852 {
853 register struct filedesc *fdp = p->p_fd;
854 int i;
855 struct file *fp;
856 int n = 0;
857
858 for (i = 0; i < nfd; i++, fds++) {
859 if ((u_int)fds->fd >= fdp->fd_nfiles) {
860 fds->revents = POLLNVAL;
861 n++;
862 } else {
863 fp = fdp->fd_ofiles[fds->fd];
864 if (fp == 0) {
865 fds->revents = POLLNVAL;
866 n++;
867 } else {
868 fds->revents = (*fp->f_ops->fo_poll)(fp,
869 fds->events | POLLERR | POLLHUP, p);
870 if (fds->revents != 0)
871 n++;
872 }
873 }
874 }
875 *retval = n;
876 return (0);
877 }
878
879 /*ARGSUSED*/
880 int
881 seltrue(dev, events, p)
882 dev_t dev;
883 int events;
884 struct proc *p;
885 {
886
887 return (events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
888 }
889
890 /*
891 * Record a select request.
892 */
893 void
894 selrecord(selector, sip)
895 struct proc *selector;
896 struct selinfo *sip;
897 {
898 struct proc *p;
899 pid_t mypid;
900
901 mypid = selector->p_pid;
902 if (sip->si_pid == mypid)
903 return;
904 if (sip->si_pid && (p = pfind(sip->si_pid)) &&
905 p->p_wchan == (caddr_t)&selwait)
906 sip->si_flags |= SI_COLL;
907 else
908 sip->si_pid = mypid;
909 }
910
911 /*
912 * Do a wakeup when a selectable event occurs.
913 */
914 void
915 selwakeup(sip)
916 register struct selinfo *sip;
917 {
918 register struct proc *p;
919 int s;
920
921 if (sip->si_pid == 0)
922 return;
923 if (sip->si_flags & SI_COLL) {
924 nselcoll++;
925 sip->si_flags &= ~SI_COLL;
926 wakeup((caddr_t)&selwait);
927 }
928 p = pfind(sip->si_pid);
929 sip->si_pid = 0;
930 if (p != NULL) {
931 s = splhigh();
932 if (p->p_wchan == (caddr_t)&selwait) {
933 if (p->p_stat == SSLEEP)
934 setrunnable(p);
935 else
936 unsleep(p);
937 } else if (p->p_flag & P_SELECT)
938 p->p_flag &= ~P_SELECT;
939 splx(s);
940 }
941 }
942