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