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