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