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