]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/sys_generic.c
This commit was generated by cvs2svn to compensate for changes in r92289,
[FreeBSD/FreeBSD.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$
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/fcntl.h>
50 #include <sys/file.h>
51 #include <sys/proc.h>
52 #include <sys/signalvar.h>
53 #include <sys/socketvar.h>
54 #include <sys/uio.h>
55 #include <sys/kernel.h>
56 #include <sys/malloc.h>
57 #include <sys/poll.h>
58 #include <sys/resourcevar.h>
59 #include <sys/selinfo.h>
60 #include <sys/sysctl.h>
61 #include <sys/sysent.h>
62 #include <sys/bio.h>
63 #include <sys/buf.h>
64 #include <sys/condvar.h>
65 #ifdef KTRACE
66 #include <sys/ktrace.h>
67 #endif
68 #include <vm/vm.h>
69 #include <vm/vm_page.h>
70
71 #include <machine/limits.h>
72
73 static MALLOC_DEFINE(M_IOCTLOPS, "ioctlops", "ioctl data buffer");
74 static MALLOC_DEFINE(M_SELECT, "select", "select() buffer");
75 MALLOC_DEFINE(M_IOV, "iov", "large iov's");
76
77 static int      pollscan(struct thread *, struct pollfd *, u_int);
78 static int      selscan(struct thread *, fd_mask **, fd_mask **, int);
79 static int      dofileread(struct thread *, struct file *, int, void *,
80                     size_t, off_t, int);
81 static int      dofilewrite(struct thread *, struct file *, int,
82                     const void *, size_t, off_t, int);
83
84 /*
85  * Read system call.
86  */
87 #ifndef _SYS_SYSPROTO_H_
88 struct read_args {
89         int     fd;
90         void    *buf;
91         size_t  nbyte;
92 };
93 #endif
94 /*
95  * MPSAFE
96  */
97 int
98 read(td, uap)
99         struct thread *td;
100         struct read_args *uap;
101 {
102         struct file *fp;
103         int error;
104
105         mtx_lock(&Giant);
106         if ((error = fget_read(td, uap->fd, &fp)) == 0) {
107                 error = dofileread(td, fp, uap->fd, uap->buf,
108                             uap->nbyte, (off_t)-1, 0);
109                 fdrop(fp, td);
110         }
111         mtx_unlock(&Giant);
112         return(error);
113 }
114
115 /*
116  * Pread system call
117  */
118 #ifndef _SYS_SYSPROTO_H_
119 struct pread_args {
120         int     fd;
121         void    *buf;
122         size_t  nbyte;
123         int     pad;
124         off_t   offset;
125 };
126 #endif
127 /*
128  * MPSAFE
129  */
130 int
131 pread(td, uap)
132         struct thread *td;
133         struct pread_args *uap;
134 {
135         struct file *fp;
136         int error;
137
138         if ((error = fget_read(td, uap->fd, &fp)) != 0)
139                 return (error);
140         mtx_lock(&Giant);
141         if (fp->f_type != DTYPE_VNODE) {
142                 error = ESPIPE;
143         } else {
144                 error = dofileread(td, fp, uap->fd, uap->buf, uap->nbyte, 
145                             uap->offset, FOF_OFFSET);
146         }
147         fdrop(fp, td);
148         mtx_unlock(&Giant);
149         return(error);
150 }
151
152 /*
153  * Code common for read and pread
154  */
155 int
156 dofileread(td, fp, fd, buf, nbyte, offset, flags)
157         struct thread *td;
158         struct file *fp;
159         int fd, flags;
160         void *buf;
161         size_t nbyte;
162         off_t offset;
163 {
164         struct uio auio;
165         struct iovec aiov;
166         long cnt, error = 0;
167 #ifdef KTRACE
168         struct iovec ktriov;
169         struct uio ktruio;
170         int didktr = 0;
171 #endif
172
173         aiov.iov_base = (caddr_t)buf;
174         aiov.iov_len = nbyte;
175         auio.uio_iov = &aiov;
176         auio.uio_iovcnt = 1;
177         auio.uio_offset = offset;
178         if (nbyte > INT_MAX)
179                 return (EINVAL);
180         auio.uio_resid = nbyte;
181         auio.uio_rw = UIO_READ;
182         auio.uio_segflg = UIO_USERSPACE;
183         auio.uio_td = td;
184 #ifdef KTRACE
185         /*
186          * if tracing, save a copy of iovec
187          */
188         if (KTRPOINT(td->td_proc, KTR_GENIO)) {
189                 ktriov = aiov;
190                 ktruio = auio;
191                 didktr = 1;
192         }
193 #endif
194         cnt = nbyte;
195
196         if ((error = fo_read(fp, &auio, fp->f_cred, flags, td))) {
197                 if (auio.uio_resid != cnt && (error == ERESTART ||
198                     error == EINTR || error == EWOULDBLOCK))
199                         error = 0;
200         }
201         cnt -= auio.uio_resid;
202 #ifdef KTRACE
203         if (didktr && error == 0) {
204                 ktruio.uio_iov = &ktriov;
205                 ktruio.uio_resid = cnt;
206                 ktrgenio(td->td_proc->p_tracep, fd, UIO_READ, &ktruio, error);
207         }
208 #endif
209         td->td_retval[0] = cnt;
210         return (error);
211 }
212
213 /*
214  * Scatter read system call.
215  */
216 #ifndef _SYS_SYSPROTO_H_
217 struct readv_args {
218         int     fd;
219         struct  iovec *iovp;
220         u_int   iovcnt;
221 };
222 #endif
223 /*
224  * MPSAFE
225  */
226 int
227 readv(td, uap)
228         struct thread *td;
229         struct readv_args *uap;
230 {
231         struct file *fp;
232         struct uio auio;
233         struct iovec *iov;
234         struct iovec *needfree;
235         struct iovec aiov[UIO_SMALLIOV];
236         long i, cnt, error = 0;
237         u_int iovlen;
238 #ifdef KTRACE
239         struct iovec *ktriov = NULL;
240         struct uio ktruio;
241 #endif
242         mtx_lock(&Giant);
243
244         if ((error = fget_read(td, uap->fd, &fp)) != 0)
245                 goto done2;
246         /* note: can't use iovlen until iovcnt is validated */
247         iovlen = uap->iovcnt * sizeof (struct iovec);
248         if (uap->iovcnt > UIO_SMALLIOV) {
249                 if (uap->iovcnt > UIO_MAXIOV) {
250                         error = EINVAL;
251                         goto done2;
252                 }
253                 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
254                 needfree = iov;
255         } else {
256                 iov = aiov;
257                 needfree = NULL;
258         }
259         auio.uio_iov = iov;
260         auio.uio_iovcnt = uap->iovcnt;
261         auio.uio_rw = UIO_READ;
262         auio.uio_segflg = UIO_USERSPACE;
263         auio.uio_td = td;
264         auio.uio_offset = -1;
265         if ((error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen)))
266                 goto done;
267         auio.uio_resid = 0;
268         for (i = 0; i < uap->iovcnt; i++) {
269                 if (iov->iov_len > INT_MAX - auio.uio_resid) {
270                         error = EINVAL;
271                         goto done;
272                 }
273                 auio.uio_resid += iov->iov_len;
274                 iov++;
275         }
276 #ifdef KTRACE
277         /*
278          * if tracing, save a copy of iovec
279          */
280         if (KTRPOINT(td->td_proc, KTR_GENIO))  {
281                 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
282                 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
283                 ktruio = auio;
284         }
285 #endif
286         cnt = auio.uio_resid;
287         if ((error = fo_read(fp, &auio, fp->f_cred, 0, td))) {
288                 if (auio.uio_resid != cnt && (error == ERESTART ||
289                     error == EINTR || error == EWOULDBLOCK))
290                         error = 0;
291         }
292         cnt -= auio.uio_resid;
293 #ifdef KTRACE
294         if (ktriov != NULL) {
295                 if (error == 0) {
296                         ktruio.uio_iov = ktriov;
297                         ktruio.uio_resid = cnt;
298                         ktrgenio(td->td_proc->p_tracep, uap->fd, UIO_READ, &ktruio,
299                             error);
300                 }
301                 FREE(ktriov, M_TEMP);
302         }
303 #endif
304         td->td_retval[0] = cnt;
305 done:
306         fdrop(fp, td);
307         if (needfree)
308                 FREE(needfree, M_IOV);
309 done2:
310         mtx_unlock(&Giant);
311         return (error);
312 }
313
314 /*
315  * Write system call
316  */
317 #ifndef _SYS_SYSPROTO_H_
318 struct write_args {
319         int     fd;
320         const void *buf;
321         size_t  nbyte;
322 };
323 #endif
324 /*
325  * MPSAFE
326  */
327 int
328 write(td, uap)
329         struct thread *td;
330         struct write_args *uap;
331 {
332         struct file *fp;
333         int error;
334
335         mtx_lock(&Giant);
336         if ((error = fget_write(td, uap->fd, &fp)) == 0) {
337                 error = dofilewrite(td, fp, uap->fd, uap->buf, uap->nbyte,
338                             (off_t)-1, 0);
339                 fdrop(fp, td);
340         } else {
341                 error = EBADF;  /* XXX this can't be right */
342         }
343         mtx_unlock(&Giant);
344         return(error);
345 }
346
347 /*
348  * Pwrite system call
349  */
350 #ifndef _SYS_SYSPROTO_H_
351 struct pwrite_args {
352         int     fd;
353         const void *buf;
354         size_t  nbyte;
355         int     pad;
356         off_t   offset;
357 };
358 #endif
359 /*
360  * MPSAFE
361  */
362 int
363 pwrite(td, uap)
364         struct thread *td;
365         struct pwrite_args *uap;
366 {
367         struct file *fp;
368         int error;
369
370         if ((error = fget_write(td, uap->fd, &fp)) == 0) {
371                 mtx_lock(&Giant);
372                 if (fp->f_type == DTYPE_VNODE) {
373                         error = dofilewrite(td, fp, uap->fd, uap->buf,
374                                     uap->nbyte, uap->offset, FOF_OFFSET);
375                 } else {
376                         error = ESPIPE;
377                 }
378                 fdrop(fp, td);
379                 mtx_unlock(&Giant);
380         } else {
381                 error = EBADF;  /* this can't be right */
382         }
383         return(error);
384 }
385
386 static int
387 dofilewrite(td, fp, fd, buf, nbyte, offset, flags)
388         struct thread *td;
389         struct file *fp;
390         int fd, flags;
391         const void *buf;
392         size_t nbyte;
393         off_t offset;
394 {
395         struct uio auio;
396         struct iovec aiov;
397         long cnt, error = 0;
398 #ifdef KTRACE
399         struct iovec ktriov;
400         struct uio ktruio;
401         int didktr = 0;
402 #endif
403
404         aiov.iov_base = (void *)(uintptr_t)buf;
405         aiov.iov_len = nbyte;
406         auio.uio_iov = &aiov;
407         auio.uio_iovcnt = 1;
408         auio.uio_offset = offset;
409         if (nbyte > INT_MAX)
410                 return (EINVAL);
411         auio.uio_resid = nbyte;
412         auio.uio_rw = UIO_WRITE;
413         auio.uio_segflg = UIO_USERSPACE;
414         auio.uio_td = td;
415 #ifdef KTRACE
416         /*
417          * if tracing, save a copy of iovec and uio
418          */
419         if (KTRPOINT(td->td_proc, KTR_GENIO)) {
420                 ktriov = aiov;
421                 ktruio = auio;
422                 didktr = 1;
423         }
424 #endif
425         cnt = nbyte;
426         if (fp->f_type == DTYPE_VNODE)
427                 bwillwrite();
428         if ((error = fo_write(fp, &auio, fp->f_cred, flags, td))) {
429                 if (auio.uio_resid != cnt && (error == ERESTART ||
430                     error == EINTR || error == EWOULDBLOCK))
431                         error = 0;
432                 if (error == EPIPE) {
433                         PROC_LOCK(td->td_proc);
434                         psignal(td->td_proc, SIGPIPE);
435                         PROC_UNLOCK(td->td_proc);
436                 }
437         }
438         cnt -= auio.uio_resid;
439 #ifdef KTRACE
440         if (didktr && error == 0) {
441                 ktruio.uio_iov = &ktriov;
442                 ktruio.uio_resid = cnt;
443                 ktrgenio(td->td_proc->p_tracep, fd, UIO_WRITE, &ktruio, error);
444         }
445 #endif
446         td->td_retval[0] = cnt;
447         return (error);
448 }
449
450 /*
451  * Gather write system call
452  */
453 #ifndef _SYS_SYSPROTO_H_
454 struct writev_args {
455         int     fd;
456         struct  iovec *iovp;
457         u_int   iovcnt;
458 };
459 #endif
460 /*
461  * MPSAFE
462  */
463 int
464 writev(td, uap)
465         struct thread *td;
466         register struct writev_args *uap;
467 {
468         struct file *fp;
469         struct uio auio;
470         register struct iovec *iov;
471         struct iovec *needfree;
472         struct iovec aiov[UIO_SMALLIOV];
473         long i, cnt, error = 0;
474         u_int iovlen;
475 #ifdef KTRACE
476         struct iovec *ktriov = NULL;
477         struct uio ktruio;
478 #endif
479
480         mtx_lock(&Giant);
481         if ((error = fget_write(td, uap->fd, &fp)) != 0) {
482                 error = EBADF;
483                 goto done2;
484         }
485         /* note: can't use iovlen until iovcnt is validated */
486         iovlen = uap->iovcnt * sizeof (struct iovec);
487         if (uap->iovcnt > UIO_SMALLIOV) {
488                 if (uap->iovcnt > UIO_MAXIOV) {
489                         needfree = NULL;
490                         error = EINVAL;
491                         goto done;
492                 }
493                 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
494                 needfree = iov;
495         } else {
496                 iov = aiov;
497                 needfree = NULL;
498         }
499         auio.uio_iov = iov;
500         auio.uio_iovcnt = uap->iovcnt;
501         auio.uio_rw = UIO_WRITE;
502         auio.uio_segflg = UIO_USERSPACE;
503         auio.uio_td = td;
504         auio.uio_offset = -1;
505         if ((error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen)))
506                 goto done;
507         auio.uio_resid = 0;
508         for (i = 0; i < uap->iovcnt; i++) {
509                 if (iov->iov_len > INT_MAX - auio.uio_resid) {
510                         error = EINVAL;
511                         goto done;
512                 }
513                 auio.uio_resid += iov->iov_len;
514                 iov++;
515         }
516 #ifdef KTRACE
517         /*
518          * if tracing, save a copy of iovec and uio
519          */
520         if (KTRPOINT(td->td_proc, KTR_GENIO))  {
521                 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
522                 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
523                 ktruio = auio;
524         }
525 #endif
526         cnt = auio.uio_resid;
527         if (fp->f_type == DTYPE_VNODE)
528                 bwillwrite();
529         if ((error = fo_write(fp, &auio, fp->f_cred, 0, td))) {
530                 if (auio.uio_resid != cnt && (error == ERESTART ||
531                     error == EINTR || error == EWOULDBLOCK))
532                         error = 0;
533                 if (error == EPIPE) {
534                         PROC_LOCK(td->td_proc);
535                         psignal(td->td_proc, SIGPIPE);
536                         PROC_UNLOCK(td->td_proc);
537                 }
538         }
539         cnt -= auio.uio_resid;
540 #ifdef KTRACE
541         if (ktriov != NULL) {
542                 if (error == 0) {
543                         ktruio.uio_iov = ktriov;
544                         ktruio.uio_resid = cnt;
545                         ktrgenio(td->td_proc->p_tracep, uap->fd, UIO_WRITE, &ktruio,
546                             error);
547                 }
548                 FREE(ktriov, M_TEMP);
549         }
550 #endif
551         td->td_retval[0] = cnt;
552 done:
553         fdrop(fp, td);
554         if (needfree)
555                 FREE(needfree, M_IOV);
556 done2:
557         mtx_unlock(&Giant);
558         return (error);
559 }
560
561 /*
562  * Ioctl system call
563  */
564 #ifndef _SYS_SYSPROTO_H_
565 struct ioctl_args {
566         int     fd;
567         u_long  com;
568         caddr_t data;
569 };
570 #endif
571 /*
572  * MPSAFE
573  */
574 /* ARGSUSED */
575 int
576 ioctl(td, uap)
577         struct thread *td;
578         register struct ioctl_args *uap;
579 {
580         struct file *fp;
581         register struct filedesc *fdp;
582         register u_long com;
583         int error = 0;
584         register u_int size;
585         caddr_t data, memp;
586         int tmp;
587 #define STK_PARAMS      128
588         union {
589             char stkbuf[STK_PARAMS];
590             long align;
591         } ubuf;
592
593         if ((error = fget(td, uap->fd, &fp)) != 0)
594                 return (error);
595         mtx_lock(&Giant);
596         if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
597                 fdrop(fp, td);
598                 mtx_unlock(&Giant);
599                 return (EBADF);
600         }
601         fdp = td->td_proc->p_fd;
602         switch (com = uap->com) {
603         case FIONCLEX:
604                 FILEDESC_LOCK(fdp);
605                 fdp->fd_ofileflags[uap->fd] &= ~UF_EXCLOSE;
606                 FILEDESC_UNLOCK(fdp);
607                 fdrop(fp, td);
608                 mtx_unlock(&Giant);
609                 return (0);
610         case FIOCLEX:
611                 FILEDESC_LOCK(fdp);
612                 fdp->fd_ofileflags[uap->fd] |= UF_EXCLOSE;
613                 FILEDESC_UNLOCK(fdp);
614                 fdrop(fp, td);
615                 mtx_unlock(&Giant);
616                 return (0);
617         }
618
619         /*
620          * Interpret high order word to find amount of data to be
621          * copied to/from the user's address space.
622          */
623         size = IOCPARM_LEN(com);
624         if (size > IOCPARM_MAX) {
625                 fdrop(fp, td);
626                 mtx_unlock(&Giant);
627                 return (ENOTTY);
628         }
629
630         memp = NULL;
631         if (size > sizeof (ubuf.stkbuf)) {
632                 memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK);
633                 data = memp;
634         } else {
635                 data = ubuf.stkbuf;
636         }
637         if (com&IOC_IN) {
638                 if (size) {
639                         error = copyin(uap->data, data, (u_int)size);
640                         if (error) {
641                                 if (memp)
642                                         free(memp, M_IOCTLOPS);
643                                 fdrop(fp, td);
644                                 goto done;
645                         }
646                 } else {
647                         *(caddr_t *)data = uap->data;
648                 }
649         } else if ((com&IOC_OUT) && size) {
650                 /*
651                  * Zero the buffer so the user always
652                  * gets back something deterministic.
653                  */
654                 bzero(data, size);
655         } else if (com&IOC_VOID) {
656                 *(caddr_t *)data = uap->data;
657         }
658
659         switch (com) {
660
661         case FIONBIO:
662                 FILE_LOCK(fp);
663                 if ((tmp = *(int *)data))
664                         fp->f_flag |= FNONBLOCK;
665                 else
666                         fp->f_flag &= ~FNONBLOCK;
667                 FILE_UNLOCK(fp);
668                 error = fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, td);
669                 break;
670
671         case FIOASYNC:
672                 FILE_LOCK(fp);
673                 if ((tmp = *(int *)data))
674                         fp->f_flag |= FASYNC;
675                 else
676                         fp->f_flag &= ~FASYNC;
677                 FILE_UNLOCK(fp);
678                 error = fo_ioctl(fp, FIOASYNC, (caddr_t)&tmp, td);
679                 break;
680
681         default:
682                 error = fo_ioctl(fp, com, data, td);
683                 /*
684                  * Copy any data to user, size was
685                  * already set and checked above.
686                  */
687                 if (error == 0 && (com&IOC_OUT) && size)
688                         error = copyout(data, uap->data, (u_int)size);
689                 break;
690         }
691         if (memp)
692                 free(memp, M_IOCTLOPS);
693         fdrop(fp, td);
694 done:
695         mtx_unlock(&Giant);
696         return (error);
697 }
698
699 /*
700  * sellock and selwait are initialized in selectinit() via SYSINIT.
701  */
702 struct mtx      sellock;
703 struct cv       selwait;
704 int     nselcoll;       /* Select collisions since boot */
705 SYSCTL_INT(_kern, OID_AUTO, nselcoll, CTLFLAG_RD, &nselcoll, 0, "");
706
707 /*
708  * Select system call.
709  */
710 #ifndef _SYS_SYSPROTO_H_
711 struct select_args {
712         int     nd;
713         fd_set  *in, *ou, *ex;
714         struct  timeval *tv;
715 };
716 #endif
717 /*
718  * MPSAFE
719  */
720 int
721 select(td, uap)
722         register struct thread *td;
723         register struct select_args *uap;
724 {
725         struct filedesc *fdp;
726         /*
727          * The magic 2048 here is chosen to be just enough for FD_SETSIZE
728          * infds with the new FD_SETSIZE of 1024, and more than enough for
729          * FD_SETSIZE infds, outfds and exceptfds with the old FD_SETSIZE
730          * of 256.
731          */
732         fd_mask s_selbits[howmany(2048, NFDBITS)];
733         fd_mask *ibits[3], *obits[3], *selbits, *sbp;
734         struct timeval atv, rtv, ttv;
735         int ncoll, error, timo;
736         u_int nbufbytes, ncpbytes, nfdbits;
737
738         if (uap->nd < 0)
739                 return (EINVAL);
740         fdp = td->td_proc->p_fd;
741         mtx_lock(&Giant);
742         FILEDESC_LOCK(fdp);
743
744         if (uap->nd > td->td_proc->p_fd->fd_nfiles)
745                 uap->nd = td->td_proc->p_fd->fd_nfiles;   /* forgiving; slightly wrong */
746         FILEDESC_UNLOCK(fdp);
747
748         /*
749          * Allocate just enough bits for the non-null fd_sets.  Use the
750          * preallocated auto buffer if possible.
751          */
752         nfdbits = roundup(uap->nd, NFDBITS);
753         ncpbytes = nfdbits / NBBY;
754         nbufbytes = 0;
755         if (uap->in != NULL)
756                 nbufbytes += 2 * ncpbytes;
757         if (uap->ou != NULL)
758                 nbufbytes += 2 * ncpbytes;
759         if (uap->ex != NULL)
760                 nbufbytes += 2 * ncpbytes;
761         if (nbufbytes <= sizeof s_selbits)
762                 selbits = &s_selbits[0];
763         else
764                 selbits = malloc(nbufbytes, M_SELECT, M_WAITOK);
765
766         /*
767          * Assign pointers into the bit buffers and fetch the input bits.
768          * Put the output buffers together so that they can be bzeroed
769          * together.
770          */
771         sbp = selbits;
772 #define getbits(name, x) \
773         do {                                                            \
774                 if (uap->name == NULL)                                  \
775                         ibits[x] = NULL;                                \
776                 else {                                                  \
777                         ibits[x] = sbp + nbufbytes / 2 / sizeof *sbp;   \
778                         obits[x] = sbp;                                 \
779                         sbp += ncpbytes / sizeof *sbp;                  \
780                         error = copyin(uap->name, ibits[x], ncpbytes);  \
781                         if (error != 0)                                 \
782                                 goto done_nosellock;                    \
783                 }                                                       \
784         } while (0)
785         getbits(in, 0);
786         getbits(ou, 1);
787         getbits(ex, 2);
788 #undef  getbits
789         if (nbufbytes != 0)
790                 bzero(selbits, nbufbytes / 2);
791
792         if (uap->tv) {
793                 error = copyin((caddr_t)uap->tv, (caddr_t)&atv,
794                         sizeof (atv));
795                 if (error)
796                         goto done_nosellock;
797                 if (itimerfix(&atv)) {
798                         error = EINVAL;
799                         goto done_nosellock;
800                 }
801                 getmicrouptime(&rtv);
802                 timevaladd(&atv, &rtv);
803         } else {
804                 atv.tv_sec = 0;
805                 atv.tv_usec = 0;
806         }
807         timo = 0;
808         mtx_lock(&sellock);
809 retry:
810         ncoll = nselcoll;
811         mtx_lock_spin(&sched_lock);
812         td->td_flags |= TDF_SELECT;
813         mtx_unlock_spin(&sched_lock);
814         mtx_unlock(&sellock);
815
816         /* XXX Is there a better place for this? */
817         TAILQ_INIT(&td->td_selq);
818         error = selscan(td, ibits, obits, uap->nd);
819         mtx_lock(&sellock);
820         if (error || td->td_retval[0])
821                 goto done;
822         if (atv.tv_sec || atv.tv_usec) {
823                 getmicrouptime(&rtv);
824                 if (timevalcmp(&rtv, &atv, >=))
825                         goto done;
826                 ttv = atv;
827                 timevalsub(&ttv, &rtv);
828                 timo = ttv.tv_sec > 24 * 60 * 60 ?
829                     24 * 60 * 60 * hz : tvtohz(&ttv);
830         }
831
832         /*
833          * An event of interest may occur while we do not hold
834          * sellock, so check TDF_SELECT and the number of
835          * collisions and rescan the file descriptors if
836          * necessary.
837          */
838         mtx_lock_spin(&sched_lock);
839         if ((td->td_flags & TDF_SELECT) == 0 || nselcoll != ncoll) {
840                 mtx_unlock_spin(&sched_lock);
841                 goto retry;
842         }
843         mtx_unlock_spin(&sched_lock);
844
845         if (timo > 0)
846                 error = cv_timedwait_sig(&selwait, &sellock, timo);
847         else
848                 error = cv_wait_sig(&selwait, &sellock);
849         
850         if (error == 0)
851                 goto retry;
852
853 done:
854         clear_selinfo_list(td);
855         mtx_lock_spin(&sched_lock);
856         td->td_flags &= ~TDF_SELECT;
857         mtx_unlock_spin(&sched_lock);
858         mtx_unlock(&sellock);
859
860 done_nosellock:
861         /* select is not restarted after signals... */
862         if (error == ERESTART)
863                 error = EINTR;
864         if (error == EWOULDBLOCK)
865                 error = 0;
866 #define putbits(name, x) \
867         if (uap->name && (error2 = copyout(obits[x], uap->name, ncpbytes))) \
868                 error = error2;
869         if (error == 0) {
870                 int error2;
871
872                 putbits(in, 0);
873                 putbits(ou, 1);
874                 putbits(ex, 2);
875 #undef putbits
876         }
877         if (selbits != &s_selbits[0])
878                 free(selbits, M_SELECT);
879
880         mtx_unlock(&Giant);
881         return (error);
882 }
883
884 static int
885 selscan(td, ibits, obits, nfd)
886         struct thread *td;
887         fd_mask **ibits, **obits;
888         int nfd;
889 {
890         int msk, i, fd;
891         fd_mask bits;
892         struct file *fp;
893         int n = 0;
894         /* Note: backend also returns POLLHUP/POLLERR if appropriate. */
895         static int flag[3] = { POLLRDNORM, POLLWRNORM, POLLRDBAND };
896         struct filedesc *fdp = td->td_proc->p_fd;
897
898         FILEDESC_LOCK(fdp);
899         for (msk = 0; msk < 3; msk++) {
900                 if (ibits[msk] == NULL)
901                         continue;
902                 for (i = 0; i < nfd; i += NFDBITS) {
903                         bits = ibits[msk][i/NFDBITS];
904                         /* ffs(int mask) not portable, fd_mask is long */
905                         for (fd = i; bits && fd < nfd; fd++, bits >>= 1) {
906                                 if (!(bits & 1))
907                                         continue;
908                                 if ((fp = fget_locked(fdp, fd)) == NULL) {
909                                         FILEDESC_UNLOCK(fdp);
910                                         return (EBADF);
911                                 }
912                                 if (fo_poll(fp, flag[msk], fp->f_cred, td)) {
913                                         obits[msk][(fd)/NFDBITS] |=
914                                             ((fd_mask)1 << ((fd) % NFDBITS));
915                                         n++;
916                                 }
917                         }
918                 }
919         }
920         FILEDESC_UNLOCK(fdp);
921         td->td_retval[0] = n;
922         return (0);
923 }
924
925 /*
926  * Poll system call.
927  */
928 #ifndef _SYS_SYSPROTO_H_
929 struct poll_args {
930         struct pollfd *fds;
931         u_int   nfds;
932         int     timeout;
933 };
934 #endif
935 /*
936  * MPSAFE
937  */
938 int
939 poll(td, uap)
940         struct thread *td;
941         struct poll_args *uap;
942 {
943         caddr_t bits;
944         char smallbits[32 * sizeof(struct pollfd)];
945         struct timeval atv, rtv, ttv;
946         int ncoll, error = 0, timo;
947         u_int nfds;
948         size_t ni;
949
950         nfds = SCARG(uap, nfds);
951
952         mtx_lock(&Giant);
953         /*
954          * This is kinda bogus.  We have fd limits, but that is not
955          * really related to the size of the pollfd array.  Make sure
956          * we let the process use at least FD_SETSIZE entries and at
957          * least enough for the current limits.  We want to be reasonably
958          * safe, but not overly restrictive.
959          */
960         if ((nfds > td->td_proc->p_rlimit[RLIMIT_NOFILE].rlim_cur) &&
961             (nfds > FD_SETSIZE)) {
962                 error = EINVAL;
963                 goto done2;
964         }
965         ni = nfds * sizeof(struct pollfd);
966         if (ni > sizeof(smallbits))
967                 bits = malloc(ni, M_TEMP, M_WAITOK);
968         else
969                 bits = smallbits;
970         error = copyin(SCARG(uap, fds), bits, ni);
971         if (error)
972                 goto done_nosellock;
973         if (SCARG(uap, timeout) != INFTIM) {
974                 atv.tv_sec = SCARG(uap, timeout) / 1000;
975                 atv.tv_usec = (SCARG(uap, timeout) % 1000) * 1000;
976                 if (itimerfix(&atv)) {
977                         error = EINVAL;
978                         goto done_nosellock;
979                 }
980                 getmicrouptime(&rtv);
981                 timevaladd(&atv, &rtv);
982         } else {
983                 atv.tv_sec = 0;
984                 atv.tv_usec = 0;
985         }
986         timo = 0;
987         mtx_lock(&sellock);
988 retry:
989         ncoll = nselcoll;
990         mtx_lock_spin(&sched_lock);
991         td->td_flags |= TDF_SELECT;
992         mtx_unlock_spin(&sched_lock);
993         mtx_unlock(&sellock);
994
995         /* XXX Is there a better place for this? */
996         TAILQ_INIT(&td->td_selq);
997         error = pollscan(td, (struct pollfd *)bits, nfds);
998         mtx_lock(&sellock);
999         if (error || td->td_retval[0])
1000                 goto done;
1001         if (atv.tv_sec || atv.tv_usec) {
1002                 getmicrouptime(&rtv);
1003                 if (timevalcmp(&rtv, &atv, >=))
1004                         goto done;
1005                 ttv = atv;
1006                 timevalsub(&ttv, &rtv);
1007                 timo = ttv.tv_sec > 24 * 60 * 60 ?
1008                     24 * 60 * 60 * hz : tvtohz(&ttv);
1009         }
1010         /*
1011          * An event of interest may occur while we do not hold
1012          * sellock, so check TDF_SELECT and the number of collisions
1013          * and rescan the file descriptors if necessary.
1014          */
1015         mtx_lock_spin(&sched_lock);
1016         if ((td->td_flags & TDF_SELECT) == 0 || nselcoll != ncoll) {
1017                 mtx_unlock_spin(&sched_lock);
1018                 goto retry;
1019         }
1020         mtx_unlock_spin(&sched_lock);
1021
1022         if (timo > 0)
1023                 error = cv_timedwait_sig(&selwait, &sellock, timo);
1024         else
1025                 error = cv_wait_sig(&selwait, &sellock);
1026
1027         if (error == 0)
1028                 goto retry;
1029
1030 done:
1031         clear_selinfo_list(td);
1032         mtx_lock_spin(&sched_lock);
1033         td->td_flags &= ~TDF_SELECT;
1034         mtx_unlock_spin(&sched_lock);
1035         mtx_unlock(&sellock);
1036
1037 done_nosellock:
1038         /* poll is not restarted after signals... */
1039         if (error == ERESTART)
1040                 error = EINTR;
1041         if (error == EWOULDBLOCK)
1042                 error = 0;
1043         if (error == 0) {
1044                 error = copyout(bits, SCARG(uap, fds), ni);
1045                 if (error)
1046                         goto out;
1047         }
1048 out:
1049         if (ni > sizeof(smallbits))
1050                 free(bits, M_TEMP);
1051 done2:
1052         mtx_unlock(&Giant);
1053         return (error);
1054 }
1055
1056 static int
1057 pollscan(td, fds, nfd)
1058         struct thread *td;
1059         struct pollfd *fds;
1060         u_int nfd;
1061 {
1062         register struct filedesc *fdp = td->td_proc->p_fd;
1063         int i;
1064         struct file *fp;
1065         int n = 0;
1066
1067         FILEDESC_LOCK(fdp);
1068         for (i = 0; i < nfd; i++, fds++) {
1069                 if (fds->fd >= fdp->fd_nfiles) {
1070                         fds->revents = POLLNVAL;
1071                         n++;
1072                 } else if (fds->fd < 0) {
1073                         fds->revents = 0;
1074                 } else {
1075                         fp = fdp->fd_ofiles[fds->fd];
1076                         if (fp == NULL) {
1077                                 fds->revents = POLLNVAL;
1078                                 n++;
1079                         } else {
1080                                 /*
1081                                  * Note: backend also returns POLLHUP and
1082                                  * POLLERR if appropriate.
1083                                  */
1084                                 fds->revents = fo_poll(fp, fds->events,
1085                                     fp->f_cred, td);
1086                                 if (fds->revents != 0)
1087                                         n++;
1088                         }
1089                 }
1090         }
1091         FILEDESC_UNLOCK(fdp);
1092         td->td_retval[0] = n;
1093         return (0);
1094 }
1095
1096 /*
1097  * OpenBSD poll system call.
1098  * XXX this isn't quite a true representation..  OpenBSD uses select ops.
1099  */
1100 #ifndef _SYS_SYSPROTO_H_
1101 struct openbsd_poll_args {
1102         struct pollfd *fds;
1103         u_int   nfds;
1104         int     timeout;
1105 };
1106 #endif
1107 /*
1108  * MPSAFE
1109  */
1110 int
1111 openbsd_poll(td, uap)
1112         register struct thread *td;
1113         register struct openbsd_poll_args *uap;
1114 {
1115         return (poll(td, (struct poll_args *)uap));
1116 }
1117
1118 /*
1119  * Remove the references to the thread from all of the objects
1120  * we were polling.
1121  *
1122  * This code assumes that the underlying owner of the selinfo
1123  * structure will hold sellock before it changes it, and that
1124  * it will unlink itself from our list if it goes away.
1125  */
1126 void
1127 clear_selinfo_list(td)
1128         struct thread *td;
1129 {
1130         struct selinfo *si;
1131
1132         mtx_assert(&sellock, MA_OWNED);
1133         TAILQ_FOREACH(si, &td->td_selq, si_thrlist)
1134                 si->si_thread = NULL;
1135         TAILQ_INIT(&td->td_selq);
1136 }
1137
1138 /*ARGSUSED*/
1139 int
1140 seltrue(dev, events, td)
1141         dev_t dev;
1142         int events;
1143         struct thread *td;
1144 {
1145
1146         return (events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
1147 }
1148
1149 /*
1150  * Record a select request.
1151  */
1152 void
1153 selrecord(selector, sip)
1154         struct thread *selector;
1155         struct selinfo *sip;
1156 {
1157
1158         mtx_lock(&sellock);
1159         /*
1160          * If the thread is NULL then take ownership of selinfo
1161          * however if the thread is not NULL and the thread points to
1162          * someone else, then we have a collision, otherwise leave it alone
1163          * as we've owned it in a previous selrecord on this selinfo.
1164          */
1165         if (sip->si_thread == NULL) {
1166                 sip->si_thread = selector;
1167                 TAILQ_INSERT_TAIL(&selector->td_selq, sip, si_thrlist);
1168         } else if (sip->si_thread != selector) {
1169                 sip->si_flags |= SI_COLL;
1170         }
1171
1172         mtx_unlock(&sellock);
1173 }
1174
1175 /*
1176  * Do a wakeup when a selectable event occurs.
1177  */
1178 void
1179 selwakeup(sip)
1180         struct selinfo *sip;
1181 {
1182         struct thread *td;
1183
1184         mtx_lock(&sellock);
1185         td = sip->si_thread;
1186         if ((sip->si_flags & SI_COLL) != 0) {
1187                 nselcoll++;
1188                 sip->si_flags &= ~SI_COLL;
1189                 cv_broadcast(&selwait);
1190         }
1191         if (td == NULL) {
1192                 mtx_unlock(&sellock);
1193                 return;
1194         }
1195         TAILQ_REMOVE(&td->td_selq, sip, si_thrlist);
1196         sip->si_thread = NULL;
1197         mtx_lock_spin(&sched_lock);
1198         if (td->td_wchan == (caddr_t)&selwait) {
1199                 if (td->td_proc->p_stat == SSLEEP)
1200                         setrunnable(td);
1201                 else
1202                         cv_waitq_remove(td);
1203         } else
1204                 td->td_flags &= ~TDF_SELECT;
1205         mtx_unlock_spin(&sched_lock);
1206         mtx_unlock(&sellock);
1207 }
1208
1209 static void selectinit __P((void *));
1210 SYSINIT(select, SI_SUB_LOCK, SI_ORDER_FIRST, selectinit, NULL)
1211
1212 /* ARGSUSED*/
1213 static void
1214 selectinit(dummy)
1215         void *dummy;
1216 {
1217         cv_init(&selwait, "select");
1218         mtx_init(&sellock, "sellck", MTX_DEF);
1219 }