Merge branch 'master' into kq_devices
[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.49 2008/05/05 22:09:44 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/event.h>
49 #include <sys/filedesc.h>
50 #include <sys/filio.h>
51 #include <sys/fcntl.h>
52 #include <sys/file.h>
53 #include <sys/proc.h>
54 #include <sys/signalvar.h>
55 #include <sys/socketvar.h>
56 #include <sys/uio.h>
57 #include <sys/kernel.h>
58 #include <sys/kern_syscall.h>
59 #include <sys/malloc.h>
60 #include <sys/mapped_ioctl.h>
61 #include <sys/poll.h>
62 #include <sys/queue.h>
63 #include <sys/resourcevar.h>
64 #include <sys/socketops.h>
65 #include <sys/sysctl.h>
66 #include <sys/sysent.h>
67 #include <sys/buf.h>
68 #ifdef KTRACE
69 #include <sys/ktrace.h>
70 #endif
71 #include <vm/vm.h>
72 #include <vm/vm_page.h>
73
74 #include <sys/file2.h>
75 #include <sys/mplock2.h>
76
77 #include <machine/limits.h>
78
79 static MALLOC_DEFINE(M_IOCTLOPS, "ioctlops", "ioctl data buffer");
80 static MALLOC_DEFINE(M_IOCTLMAP, "ioctlmap", "mapped ioctl handler buffer");
81 static MALLOC_DEFINE(M_SELECT, "select", "select() buffer");
82 MALLOC_DEFINE(M_IOV, "iov", "large iov's");
83
84 typedef struct kfd_set {
85         fd_mask fds_bits[2];
86 } kfd_set;
87
88 enum select_copyin_states {
89     COPYIN_READ, COPYIN_WRITE, COPYIN_EXCEPT, COPYIN_DONE };
90
91 struct select_kevent_copyin_args {
92         kfd_set         *read_set;
93         kfd_set         *write_set;
94         kfd_set         *except_set;
95         int             active_set;     /* One of select_copyin_states */
96         struct lwp      *lwp;           /* Pointer to our lwp */
97         int             num_fds;        /* Number of file descriptors (syscall arg) */
98         int             proc_fds;       /* Processed fd's (wraps) */
99         int             error;          /* Returned to userland */
100 };
101
102 struct poll_kevent_copyin_args {
103         struct lwp      *lwp;
104         struct pollfd   *fds;
105         int             nfds;
106         int             pfds;
107         int             error;
108 };
109
110 static int      doselect(int nd, fd_set *in, fd_set *ou, fd_set *ex,
111                          struct timespec *ts, int *res);
112 static int      dopoll(int nfds, struct pollfd *fds, struct timespec *ts,
113                        int *res);
114 static int      dofileread(int, struct file *, struct uio *, int, size_t *);
115 static int      dofilewrite(int, struct file *, struct uio *, int, size_t *);
116
117 /*
118  * Read system call.
119  *
120  * MPSAFE
121  */
122 int
123 sys_read(struct read_args *uap)
124 {
125         struct thread *td = curthread;
126         struct uio auio;
127         struct iovec aiov;
128         int error;
129
130         if ((ssize_t)uap->nbyte < 0)
131                 error = EINVAL;
132
133         aiov.iov_base = uap->buf;
134         aiov.iov_len = uap->nbyte;
135         auio.uio_iov = &aiov;
136         auio.uio_iovcnt = 1;
137         auio.uio_offset = -1;
138         auio.uio_resid = uap->nbyte;
139         auio.uio_rw = UIO_READ;
140         auio.uio_segflg = UIO_USERSPACE;
141         auio.uio_td = td;
142
143         error = kern_preadv(uap->fd, &auio, 0, &uap->sysmsg_szresult);
144         return(error);
145 }
146
147 /*
148  * Positioned (Pread) read system call
149  *
150  * MPSAFE
151  */
152 int
153 sys_extpread(struct extpread_args *uap)
154 {
155         struct thread *td = curthread;
156         struct uio auio;
157         struct iovec aiov;
158         int error;
159         int flags;
160
161         if ((ssize_t)uap->nbyte < 0)
162                 return(EINVAL);
163
164         aiov.iov_base = uap->buf;
165         aiov.iov_len = uap->nbyte;
166         auio.uio_iov = &aiov;
167         auio.uio_iovcnt = 1;
168         auio.uio_offset = uap->offset;
169         auio.uio_resid = uap->nbyte;
170         auio.uio_rw = UIO_READ;
171         auio.uio_segflg = UIO_USERSPACE;
172         auio.uio_td = td;
173
174         flags = uap->flags & O_FMASK;
175         if (uap->offset != (off_t)-1)
176                 flags |= O_FOFFSET;
177
178         error = kern_preadv(uap->fd, &auio, flags, &uap->sysmsg_szresult);
179         return(error);
180 }
181
182 /*
183  * Scatter read system call.
184  *
185  * MPSAFE
186  */
187 int
188 sys_readv(struct readv_args *uap)
189 {
190         struct thread *td = curthread;
191         struct uio auio;
192         struct iovec aiov[UIO_SMALLIOV], *iov = NULL;
193         int error;
194
195         error = iovec_copyin(uap->iovp, &iov, aiov, uap->iovcnt,
196                              &auio.uio_resid);
197         if (error)
198                 return (error);
199         auio.uio_iov = iov;
200         auio.uio_iovcnt = uap->iovcnt;
201         auio.uio_offset = -1;
202         auio.uio_rw = UIO_READ;
203         auio.uio_segflg = UIO_USERSPACE;
204         auio.uio_td = td;
205
206         error = kern_preadv(uap->fd, &auio, 0, &uap->sysmsg_szresult);
207
208         iovec_free(&iov, aiov);
209         return (error);
210 }
211
212
213 /*
214  * Scatter positioned read system call.
215  *
216  * MPSAFE
217  */
218 int
219 sys_extpreadv(struct extpreadv_args *uap)
220 {
221         struct thread *td = curthread;
222         struct uio auio;
223         struct iovec aiov[UIO_SMALLIOV], *iov = NULL;
224         int error;
225         int flags;
226
227         error = iovec_copyin(uap->iovp, &iov, aiov, uap->iovcnt,
228                              &auio.uio_resid);
229         if (error)
230                 return (error);
231         auio.uio_iov = iov;
232         auio.uio_iovcnt = uap->iovcnt;
233         auio.uio_offset = uap->offset;
234         auio.uio_rw = UIO_READ;
235         auio.uio_segflg = UIO_USERSPACE;
236         auio.uio_td = td;
237
238         flags = uap->flags & O_FMASK;
239         if (uap->offset != (off_t)-1)
240                 flags |= O_FOFFSET;
241
242         error = kern_preadv(uap->fd, &auio, flags, &uap->sysmsg_szresult);
243
244         iovec_free(&iov, aiov);
245         return(error);
246 }
247
248 /*
249  * MPSAFE
250  */
251 int
252 kern_preadv(int fd, struct uio *auio, int flags, size_t *res)
253 {
254         struct thread *td = curthread;
255         struct proc *p = td->td_proc;
256         struct file *fp;
257         int error;
258
259         KKASSERT(p);
260
261         fp = holdfp(p->p_fd, fd, FREAD);
262         if (fp == NULL)
263                 return (EBADF);
264         if (flags & O_FOFFSET && fp->f_type != DTYPE_VNODE) {
265                 error = ESPIPE;
266         } else {
267                 error = dofileread(fd, fp, auio, flags, res);
268         }
269         fdrop(fp);
270         return(error);
271 }
272
273 /*
274  * Common code for readv and preadv that reads data in
275  * from a file using the passed in uio, offset, and flags.
276  *
277  * MPALMOSTSAFE - ktrace needs help
278  */
279 static int
280 dofileread(int fd, struct file *fp, struct uio *auio, int flags, size_t *res)
281 {
282         int error;
283         size_t len;
284 #ifdef KTRACE
285         struct thread *td = curthread;
286         struct iovec *ktriov = NULL;
287         struct uio ktruio;
288 #endif
289
290 #ifdef KTRACE
291         /*
292          * if tracing, save a copy of iovec
293          */
294         if (KTRPOINT(td, KTR_GENIO))  {
295                 int iovlen = auio->uio_iovcnt * sizeof(struct iovec);
296
297                 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
298                 bcopy((caddr_t)auio->uio_iov, (caddr_t)ktriov, iovlen);
299                 ktruio = *auio;
300         }
301 #endif
302         len = auio->uio_resid;
303         error = fo_read(fp, auio, fp->f_cred, flags);
304         if (error) {
305                 if (auio->uio_resid != len && (error == ERESTART ||
306                     error == EINTR || error == EWOULDBLOCK))
307                         error = 0;
308         }
309 #ifdef KTRACE
310         if (ktriov != NULL) {
311                 if (error == 0) {
312                         ktruio.uio_iov = ktriov;
313                         ktruio.uio_resid = len - auio->uio_resid;
314                         get_mplock();
315                         ktrgenio(td->td_lwp, fd, UIO_READ, &ktruio, error);
316                         rel_mplock();
317                 }
318                 FREE(ktriov, M_TEMP);
319         }
320 #endif
321         if (error == 0)
322                 *res = len - auio->uio_resid;
323
324         return(error);
325 }
326
327 /*
328  * Write system call
329  *
330  * MPSAFE
331  */
332 int
333 sys_write(struct write_args *uap)
334 {
335         struct thread *td = curthread;
336         struct uio auio;
337         struct iovec aiov;
338         int error;
339
340         if ((ssize_t)uap->nbyte < 0)
341                 error = EINVAL;
342
343         aiov.iov_base = (void *)(uintptr_t)uap->buf;
344         aiov.iov_len = uap->nbyte;
345         auio.uio_iov = &aiov;
346         auio.uio_iovcnt = 1;
347         auio.uio_offset = -1;
348         auio.uio_resid = uap->nbyte;
349         auio.uio_rw = UIO_WRITE;
350         auio.uio_segflg = UIO_USERSPACE;
351         auio.uio_td = td;
352
353         error = kern_pwritev(uap->fd, &auio, 0, &uap->sysmsg_szresult);
354
355         return(error);
356 }
357
358 /*
359  * Pwrite system call
360  *
361  * MPSAFE
362  */
363 int
364 sys_extpwrite(struct extpwrite_args *uap)
365 {
366         struct thread *td = curthread;
367         struct uio auio;
368         struct iovec aiov;
369         int error;
370         int flags;
371
372         if ((ssize_t)uap->nbyte < 0)
373                 error = EINVAL;
374
375         aiov.iov_base = (void *)(uintptr_t)uap->buf;
376         aiov.iov_len = uap->nbyte;
377         auio.uio_iov = &aiov;
378         auio.uio_iovcnt = 1;
379         auio.uio_offset = uap->offset;
380         auio.uio_resid = uap->nbyte;
381         auio.uio_rw = UIO_WRITE;
382         auio.uio_segflg = UIO_USERSPACE;
383         auio.uio_td = td;
384
385         flags = uap->flags & O_FMASK;
386         if (uap->offset != (off_t)-1)
387                 flags |= O_FOFFSET;
388         error = kern_pwritev(uap->fd, &auio, flags, &uap->sysmsg_szresult);
389         return(error);
390 }
391
392 /*
393  * MPSAFE
394  */
395 int
396 sys_writev(struct writev_args *uap)
397 {
398         struct thread *td = curthread;
399         struct uio auio;
400         struct iovec aiov[UIO_SMALLIOV], *iov = NULL;
401         int error;
402
403         error = iovec_copyin(uap->iovp, &iov, aiov, uap->iovcnt,
404                              &auio.uio_resid);
405         if (error)
406                 return (error);
407         auio.uio_iov = iov;
408         auio.uio_iovcnt = uap->iovcnt;
409         auio.uio_offset = -1;
410         auio.uio_rw = UIO_WRITE;
411         auio.uio_segflg = UIO_USERSPACE;
412         auio.uio_td = td;
413
414         error = kern_pwritev(uap->fd, &auio, 0, &uap->sysmsg_szresult);
415
416         iovec_free(&iov, aiov);
417         return (error);
418 }
419
420
421 /*
422  * Gather positioned write system call
423  *
424  * MPSAFE
425  */
426 int
427 sys_extpwritev(struct extpwritev_args *uap)
428 {
429         struct thread *td = curthread;
430         struct uio auio;
431         struct iovec aiov[UIO_SMALLIOV], *iov = NULL;
432         int error;
433         int flags;
434
435         error = iovec_copyin(uap->iovp, &iov, aiov, uap->iovcnt,
436                              &auio.uio_resid);
437         if (error)
438                 return (error);
439         auio.uio_iov = iov;
440         auio.uio_iovcnt = uap->iovcnt;
441         auio.uio_offset = uap->offset;
442         auio.uio_rw = UIO_WRITE;
443         auio.uio_segflg = UIO_USERSPACE;
444         auio.uio_td = td;
445
446         flags = uap->flags & O_FMASK;
447         if (uap->offset != (off_t)-1)
448                 flags |= O_FOFFSET;
449
450         error = kern_pwritev(uap->fd, &auio, flags, &uap->sysmsg_szresult);
451
452         iovec_free(&iov, aiov);
453         return(error);
454 }
455
456 /*
457  * MPSAFE
458  */
459 int
460 kern_pwritev(int fd, struct uio *auio, int flags, size_t *res)
461 {
462         struct thread *td = curthread;
463         struct proc *p = td->td_proc;
464         struct file *fp;
465         int error;
466
467         KKASSERT(p);
468
469         fp = holdfp(p->p_fd, fd, FWRITE);
470         if (fp == NULL)
471                 return (EBADF);
472         else if ((flags & O_FOFFSET) && fp->f_type != DTYPE_VNODE) {
473                 error = ESPIPE;
474         } else {
475                 error = dofilewrite(fd, fp, auio, flags, res);
476         }
477         
478         fdrop(fp);
479         return (error);
480 }
481
482 /*
483  * Common code for writev and pwritev that writes data to
484  * a file using the passed in uio, offset, and flags.
485  *
486  * MPALMOSTSAFE - ktrace needs help
487  */
488 static int
489 dofilewrite(int fd, struct file *fp, struct uio *auio, int flags, size_t *res)
490 {       
491         struct thread *td = curthread;
492         struct lwp *lp = td->td_lwp;
493         int error;
494         size_t len;
495 #ifdef KTRACE
496         struct iovec *ktriov = NULL;
497         struct uio ktruio;
498 #endif
499
500 #ifdef KTRACE
501         /*
502          * if tracing, save a copy of iovec and uio
503          */
504         if (KTRPOINT(td, KTR_GENIO))  {
505                 int iovlen = auio->uio_iovcnt * sizeof(struct iovec);
506
507                 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
508                 bcopy((caddr_t)auio->uio_iov, (caddr_t)ktriov, iovlen);
509                 ktruio = *auio;
510         }
511 #endif
512         len = auio->uio_resid;
513         error = fo_write(fp, auio, fp->f_cred, flags);
514         if (error) {
515                 if (auio->uio_resid != len && (error == ERESTART ||
516                     error == EINTR || error == EWOULDBLOCK))
517                         error = 0;
518                 /* Socket layer is responsible for issuing SIGPIPE. */
519                 if (error == EPIPE) {
520                         get_mplock();
521                         lwpsignal(lp->lwp_proc, lp, SIGPIPE);
522                         rel_mplock();
523                 }
524         }
525 #ifdef KTRACE
526         if (ktriov != NULL) {
527                 if (error == 0) {
528                         ktruio.uio_iov = ktriov;
529                         ktruio.uio_resid = len - auio->uio_resid;
530                         get_mplock();
531                         ktrgenio(lp, fd, UIO_WRITE, &ktruio, error);
532                         rel_mplock();
533                 }
534                 FREE(ktriov, M_TEMP);
535         }
536 #endif
537         if (error == 0)
538                 *res = len - auio->uio_resid;
539
540         return(error);
541 }
542
543 /*
544  * Ioctl system call
545  *
546  * MPALMOSTSAFE
547  */
548 int
549 sys_ioctl(struct ioctl_args *uap)
550 {
551         int error;
552
553         get_mplock();
554         error = mapped_ioctl(uap->fd, uap->com, uap->data, NULL, &uap->sysmsg);
555         rel_mplock();
556         return (error);
557 }
558
559 struct ioctl_map_entry {
560         const char *subsys;
561         struct ioctl_map_range *cmd_ranges;
562         LIST_ENTRY(ioctl_map_entry) entries;
563 };
564
565 /*
566  * The true heart of all ioctl syscall handlers (native, emulation).
567  * If map != NULL, it will be searched for a matching entry for com,
568  * and appropriate conversions/conversion functions will be utilized.
569  */
570 int
571 mapped_ioctl(int fd, u_long com, caddr_t uspc_data, struct ioctl_map *map,
572              struct sysmsg *msg)
573 {
574         struct thread *td = curthread;
575         struct proc *p = td->td_proc;
576         struct ucred *cred;
577         struct file *fp;
578         struct ioctl_map_range *iomc = NULL;
579         int error;
580         u_int size;
581         u_long ocom = com;
582         caddr_t data, memp;
583         int tmp;
584 #define STK_PARAMS      128
585         union {
586             char stkbuf[STK_PARAMS];
587             long align;
588         } ubuf;
589
590         KKASSERT(p);
591         cred = td->td_ucred;
592
593         fp = holdfp(p->p_fd, fd, FREAD|FWRITE);
594         if (fp == NULL)
595                 return(EBADF);
596
597         if (map != NULL) {      /* obey translation map */
598                 u_long maskcmd;
599                 struct ioctl_map_entry *e;
600
601                 maskcmd = com & map->mask;
602
603                 LIST_FOREACH(e, &map->mapping, entries) {
604                         for (iomc = e->cmd_ranges; iomc->start != 0 ||
605                              iomc->maptocmd != 0 || iomc->wrapfunc != NULL ||
606                              iomc->mapfunc != NULL;
607                              iomc++) {
608                                 if (maskcmd >= iomc->start &&
609                                     maskcmd <= iomc->end)
610                                         break;
611                         }
612
613                         /* Did we find a match? */
614                         if (iomc->start != 0 || iomc->maptocmd != 0 ||
615                             iomc->wrapfunc != NULL || iomc->mapfunc != NULL)
616                                 break;
617                 }
618
619                 if (iomc == NULL ||
620                     (iomc->start == 0 && iomc->maptocmd == 0
621                      && iomc->wrapfunc == NULL && iomc->mapfunc == NULL)) {
622                         kprintf("%s: 'ioctl' fd=%d, cmd=0x%lx ('%c',%d) not implemented\n",
623                                map->sys, fd, maskcmd,
624                                (int)((maskcmd >> 8) & 0xff),
625                                (int)(maskcmd & 0xff));
626                         error = EINVAL;
627                         goto done;
628                 }
629
630                 /*
631                  * If it's a non-range one to one mapping, maptocmd should be
632                  * correct. If it's a ranged one to one mapping, we pass the
633                  * original value of com, and for a range mapped to a different
634                  * range, we always need a mapping function to translate the
635                  * ioctl to our native ioctl. Ex. 6500-65ff <-> 9500-95ff
636                  */
637                 if (iomc->start == iomc->end && iomc->maptocmd == iomc->maptoend) {
638                         com = iomc->maptocmd;
639                 } else if (iomc->start == iomc->maptocmd && iomc->end == iomc->maptoend) {
640                         if (iomc->mapfunc != NULL)
641                                 com = iomc->mapfunc(iomc->start, iomc->end,
642                                                     iomc->start, iomc->end,
643                                                     com, com);
644                 } else {
645                         if (iomc->mapfunc != NULL) {
646                                 com = iomc->mapfunc(iomc->start, iomc->end,
647                                                     iomc->maptocmd, iomc->maptoend,
648                                                     com, ocom);
649                         } else {
650                                 kprintf("%s: Invalid mapping for fd=%d, cmd=%#lx ('%c',%d)\n",
651                                        map->sys, fd, maskcmd,
652                                        (int)((maskcmd >> 8) & 0xff),
653                                        (int)(maskcmd & 0xff));
654                                 error = EINVAL;
655                                 goto done;
656                         }
657                 }
658         }
659
660         switch (com) {
661         case FIONCLEX:
662                 error = fclrfdflags(p->p_fd, fd, UF_EXCLOSE);
663                 goto done;
664         case FIOCLEX:
665                 error = fsetfdflags(p->p_fd, fd, UF_EXCLOSE);
666                 goto done;
667         }
668
669         /*
670          * Interpret high order word to find amount of data to be
671          * copied to/from the user's address space.
672          */
673         size = IOCPARM_LEN(com);
674         if (size > IOCPARM_MAX) {
675                 error = ENOTTY;
676                 goto done;
677         }
678
679         memp = NULL;
680         if (size > sizeof (ubuf.stkbuf)) {
681                 memp = kmalloc(size, M_IOCTLOPS, M_WAITOK);
682                 data = memp;
683         } else {
684                 data = ubuf.stkbuf;
685         }
686         if ((com & IOC_IN) != 0) {
687                 if (size != 0) {
688                         error = copyin(uspc_data, data, (size_t)size);
689                         if (error) {
690                                 if (memp != NULL)
691                                         kfree(memp, M_IOCTLOPS);
692                                 goto done;
693                         }
694                 } else {
695                         *(caddr_t *)data = uspc_data;
696                 }
697         } else if ((com & IOC_OUT) != 0 && size) {
698                 /*
699                  * Zero the buffer so the user always
700                  * gets back something deterministic.
701                  */
702                 bzero(data, (size_t)size);
703         } else if ((com & IOC_VOID) != 0) {
704                 *(caddr_t *)data = uspc_data;
705         }
706
707         switch (com) {
708         case FIONBIO:
709                 if ((tmp = *(int *)data))
710                         fp->f_flag |= FNONBLOCK;
711                 else
712                         fp->f_flag &= ~FNONBLOCK;
713                 error = 0;
714                 break;
715
716         case FIOASYNC:
717                 if ((tmp = *(int *)data))
718                         fp->f_flag |= FASYNC;
719                 else
720                         fp->f_flag &= ~FASYNC;
721                 error = fo_ioctl(fp, FIOASYNC, (caddr_t)&tmp, cred, msg);
722                 break;
723
724         default:
725                 /*
726                  *  If there is a override function,
727                  *  call it instead of directly routing the call
728                  */
729                 if (map != NULL && iomc->wrapfunc != NULL)
730                         error = iomc->wrapfunc(fp, com, ocom, data, cred);
731                 else
732                         error = fo_ioctl(fp, com, data, cred, msg);
733                 /*
734                  * Copy any data to user, size was
735                  * already set and checked above.
736                  */
737                 if (error == 0 && (com & IOC_OUT) != 0 && size != 0)
738                         error = copyout(data, uspc_data, (size_t)size);
739                 break;
740         }
741         if (memp != NULL)
742                 kfree(memp, M_IOCTLOPS);
743 done:
744         fdrop(fp);
745         return(error);
746 }
747
748 int
749 mapped_ioctl_register_handler(struct ioctl_map_handler *he)
750 {
751         struct ioctl_map_entry *ne;
752
753         KKASSERT(he != NULL && he->map != NULL && he->cmd_ranges != NULL &&
754                  he->subsys != NULL && *he->subsys != '\0');
755
756         ne = kmalloc(sizeof(struct ioctl_map_entry), M_IOCTLMAP, M_WAITOK);
757
758         ne->subsys = he->subsys;
759         ne->cmd_ranges = he->cmd_ranges;
760
761         LIST_INSERT_HEAD(&he->map->mapping, ne, entries);
762
763         return(0);
764 }
765
766 int
767 mapped_ioctl_unregister_handler(struct ioctl_map_handler *he)
768 {
769         struct ioctl_map_entry *ne;
770
771         KKASSERT(he != NULL && he->map != NULL && he->cmd_ranges != NULL);
772
773         LIST_FOREACH(ne, &he->map->mapping, entries) {
774                 if (ne->cmd_ranges != he->cmd_ranges)
775                         continue;
776                 LIST_REMOVE(ne, entries);
777                 kfree(ne, M_IOCTLMAP);
778                 return(0);
779         }
780         return(EINVAL);
781 }
782
783 static int      nselcoll;       /* Select collisions since boot */
784 int     selwait;
785 SYSCTL_INT(_kern, OID_AUTO, nselcoll, CTLFLAG_RD, &nselcoll, 0, "");
786 static int      nseldebug;
787 SYSCTL_INT(_kern, OID_AUTO, nseldebug, CTLFLAG_RW, &nseldebug, 0, "");
788
789 /*
790  * Select system call.
791  *
792  * MPSAFE
793  */
794 int
795 sys_select(struct select_args *uap)
796 {
797         struct timeval ktv;
798         struct timespec *ktsp, kts;
799         int error;
800
801         /*
802          * Get timeout if any.
803          */
804         if (uap->tv != NULL) {
805                 error = copyin(uap->tv, &ktv, sizeof (ktv));
806                 if (error)
807                         return (error);
808                 TIMEVAL_TO_TIMESPEC(&ktv, &kts);
809                 ktsp = &kts;
810         } else {
811                 ktsp = NULL;
812         }
813
814         /*
815          * Do real work.
816          */
817         error = doselect(uap->nd, uap->in, uap->ou, uap->ex, ktsp,
818                          &uap->sysmsg_result);
819
820         return (error);
821 }
822
823
824 /*
825  * Pselect system call.
826  *
827  * MPALMOSTSAFE
828  */
829 int
830 sys_pselect(struct pselect_args *uap)
831 {
832         struct thread *td = curthread;
833         struct lwp *lp = td->td_lwp;
834         struct timespec *ktsp, kts;
835         sigset_t sigmask;
836         int error;
837
838         /*
839          * Get timeout if any.
840          */
841         if (uap->ts != NULL) {
842                 error = copyin(uap->ts, &kts, sizeof (kts));
843                 if (error)
844                         return (error);
845                 ktsp = &kts;
846         } else {
847                 ktsp = NULL;
848         }
849
850         /*
851          * Install temporary signal mask if any provided.
852          */
853         if (uap->sigmask != NULL) {
854                 error = copyin(uap->sigmask, &sigmask, sizeof(sigmask));
855                 if (error)
856                         return (error);
857                 get_mplock();
858                 lp->lwp_oldsigmask = lp->lwp_sigmask;
859                 SIG_CANTMASK(sigmask);
860                 lp->lwp_sigmask = sigmask;
861         } else {
862                 get_mplock();
863         }
864
865         /*
866          * Do real job.
867          */
868         error = doselect(uap->nd, uap->in, uap->ou, uap->ex, ktsp,
869                          &uap->sysmsg_result);
870
871         if (uap->sigmask != NULL) {
872                 /* doselect() responsible for turning ERESTART into EINTR */
873                 KKASSERT(error != ERESTART);
874                 if (error == EINTR) {
875                         /*
876                          * We can't restore the previous signal mask now
877                          * because it could block the signal that interrupted
878                          * us.  So make a note to restore it after executing
879                          * the handler.
880                          */
881                         lp->lwp_flag |= LWP_OLDMASK;
882                 } else {
883                         /*
884                          * No handler to run. Restore previous mask immediately.
885                          */
886                         lp->lwp_sigmask = lp->lwp_oldsigmask;
887                 }
888         }
889         rel_mplock();
890
891         return (error);
892 }
893
894 static int
895 select_copyin(void *arg, struct kevent *kevp, int maxevents, int *events)
896 {
897         struct select_kevent_copyin_args *skap = NULL;
898         struct kevent *kev;
899         int fd;
900         kfd_set *fdp = NULL;
901         short filter = 0;
902         u_int fflags = 0;
903
904         skap = (struct select_kevent_copyin_args *)arg;
905
906         if (*events == maxevents)
907                 return (0);
908
909         while (skap->active_set < COPYIN_DONE) {
910                 switch (skap->active_set) {
911                 case COPYIN_READ:
912                         /*
913                          * Register descriptors for the read filter
914                          */
915                         fdp = skap->read_set;
916                         filter = EVFILT_READ;
917                         fflags = 0;
918                         if (fdp)
919                                 break;
920                         ++skap->active_set;
921                         skap->proc_fds = 0;
922                         /* fall through */
923                 case COPYIN_WRITE:
924                         /*
925                          * Register descriptors for the write filter
926                          */
927                         fdp = skap->write_set;
928                         filter = EVFILT_WRITE;
929                         fflags = 0;
930                         if (fdp)
931                                 break;
932                         ++skap->active_set;
933                         skap->proc_fds = 0;
934                         /* fall through */
935                 case COPYIN_EXCEPT:
936                         /*
937                          * Register descriptors for the exception filter
938                          */
939                         fdp = skap->except_set;
940                         filter = EVFILT_EXCEPT;
941                         fflags = NOTE_OOB;
942                         if (fdp)
943                                 break;
944                         ++skap->active_set;
945                         skap->proc_fds = 0;
946                         /* fall through */
947                 case COPYIN_DONE:
948                         /*
949                          * Nothing left to register
950                          */
951                         return(0);
952                         /* NOT REACHED */
953                 }
954
955                 while (skap->proc_fds < skap->num_fds) {
956                         fd = skap->proc_fds;
957                         if (FD_ISSET(fd, fdp)) {
958                                 kev = &kevp[*events];
959                                 EV_SET(kev, fd, filter,
960                                        EV_ADD|EV_ENABLE,
961                                        fflags, 0,
962                                        (void *)skap->lwp->lwp_kqueue_serial);
963                                 FD_CLR(fd, fdp);
964                                 ++*events;
965                         }
966                         ++skap->proc_fds;
967                         if (*events == maxevents)
968                                 return (0);
969                 }
970                 skap->active_set++;
971                 skap->proc_fds = 0;
972         }
973
974         return (0);
975 }
976
977 static int
978 select_copyout(void *arg, struct kevent *kevp, int count, int *res)
979 {
980         struct select_kevent_copyin_args *skap;
981         struct kevent kev;
982         int i = 0;
983
984         skap = (struct select_kevent_copyin_args *)arg;
985
986         if (kevp[0].flags & EV_ERROR) {
987                 skap->error = kevp[0].data;
988                 return (0);
989         }
990
991         for (i = 0; i < count; ++i) {
992                 if ((u_int)kevp[i].udata != skap->lwp->lwp_kqueue_serial) {
993                         kev = kevp[i];
994                         kev.flags = EV_DISABLE|EV_DELETE;
995                         kqueue_register(&skap->lwp->lwp_kqueue, &kev);
996                         continue;
997                 }
998
999                 switch (kevp[i].filter) {
1000                 case EVFILT_READ:
1001                         FD_SET(kevp[i].ident, skap->read_set);
1002                         break;
1003                 case EVFILT_WRITE:
1004                         FD_SET(kevp[i].ident, skap->write_set);
1005                         break;
1006                 case EVFILT_EXCEPT:
1007                         FD_SET(kevp[i].ident, skap->except_set);
1008                         break;
1009                 }
1010
1011                 ++*res;
1012         }
1013
1014         return (0);
1015 }
1016
1017 /*
1018  * Copy select bits in from userland.  Allocate kernel memory if the
1019  * set is large.
1020  */
1021 static int
1022 getbits(int bytes, fd_set *in_set, kfd_set **out_set, kfd_set *tmp_set)
1023 {
1024         int error;
1025
1026         if (in_set) {
1027                 if (bytes < sizeof(*tmp_set))
1028                         *out_set = tmp_set;
1029                 else
1030                         *out_set = kmalloc(bytes, M_SELECT, M_WAITOK);
1031                 error = copyin(in_set, *out_set, bytes);
1032         } else {
1033                 *out_set = NULL;
1034                 error = 0;
1035         }
1036         return (error);
1037 }
1038
1039 /*
1040  * Copy returned select bits back out to userland.
1041  */
1042 static int
1043 putbits(int bytes, kfd_set *in_set, fd_set *out_set)
1044 {
1045         int error;
1046
1047         if (in_set) {
1048                 error = copyout(in_set, out_set, bytes);
1049         } else {
1050                 error = 0;
1051         }
1052         return (error);
1053 }
1054
1055 /*
1056  * Common code for sys_select() and sys_pselect().
1057  *
1058  * in, out and ex are userland pointers.  ts must point to validated
1059  * kernel-side timeout value or NULL for infinite timeout.  res must
1060  * point to syscall return value.
1061  */
1062 static int
1063 doselect(int nd, fd_set *read, fd_set *write, fd_set *except,
1064          struct timespec *ts, int *res)
1065 {
1066         struct proc *p = curproc;
1067         struct select_kevent_copyin_args *kap, ka;
1068         int bytes, error;
1069         kfd_set read_tmp;
1070         kfd_set write_tmp;
1071         kfd_set except_tmp;
1072
1073         *res = 0;
1074         if (nd < 0)
1075                 return (EINVAL);
1076         if (nd > p->p_fd->fd_nfiles)            /* limit kmalloc */
1077                 nd = p->p_fd->fd_nfiles;
1078
1079         kap = &ka;
1080         kap->lwp = curthread->td_lwp;
1081         kap->num_fds = nd;
1082         kap->proc_fds = 0;
1083         kap->error = 0;
1084         kap->active_set = COPYIN_READ;
1085
1086         /*
1087          * Calculate bytes based on the number of __fd_mask[] array entries
1088          * multiplied by the size of __fd_mask.
1089          */
1090         bytes = howmany(nd, __NFDBITS) * sizeof(__fd_mask);
1091
1092         error = getbits(bytes, read, &kap->read_set, &read_tmp);
1093         if (error == 0)
1094                 error = getbits(bytes, write, &kap->write_set, &write_tmp);
1095         if (error == 0)
1096                 error = getbits(bytes, except, &kap->except_set, &except_tmp);
1097         if (error)
1098                 goto done;
1099
1100         /*
1101          * NOTE: Make sure the max events passed to kern_kevent() is
1102          *       effectively unlimited.  (nd * 3) accomplishes this.
1103          *
1104          *       (*res) continues to increment as returned events are
1105          *       loaded in.
1106          */
1107         error = kern_kevent(&kap->lwp->lwp_kqueue, 0x7FFFFFFF, res, kap,
1108                             select_copyin, select_copyout, ts);
1109         if (error == 0)
1110                 error = putbits(bytes, kap->read_set, read);
1111         if (error == 0)
1112                 error = putbits(bytes, kap->write_set, write);
1113         if (error == 0)
1114                 error = putbits(bytes, kap->except_set, except);
1115
1116         /*
1117          * Cumulative error from individual events (EBADFD?)
1118          */
1119         if (kap->error)
1120                 error = kap->error;
1121
1122         /*
1123          * Clean up.
1124          */
1125 done:
1126         if (kap->read_set && kap->read_set != &read_tmp)
1127                 kfree(kap->read_set, M_SELECT);
1128         if (kap->write_set && kap->write_set != &write_tmp)
1129                 kfree(kap->write_set, M_SELECT);
1130         if (kap->except_set && kap->except_set != &except_tmp)
1131                 kfree(kap->except_set, M_SELECT);
1132
1133         kap->lwp->lwp_kqueue_serial++;
1134
1135         return (error);
1136 }
1137
1138 /*
1139  * Poll system call.
1140  *
1141  * MPSAFE
1142  */
1143 int
1144 sys_poll(struct poll_args *uap)
1145 {
1146         struct timespec ts, *tsp;
1147         int error;
1148
1149         if (uap->timeout != INFTIM) {
1150                 ts.tv_sec = uap->timeout / 1000;
1151                 ts.tv_nsec = (uap->timeout % 1000) * 1000 * 1000;
1152                 tsp = &ts;
1153         } else {
1154                 tsp = NULL;
1155         }
1156
1157         error = dopoll(uap->nfds, uap->fds, tsp, &uap->sysmsg_result);
1158
1159         return (error);
1160 }
1161
1162 static int
1163 poll_copyin(void *arg, struct kevent *kevp, int maxevents, int *events)
1164 {
1165         struct poll_kevent_copyin_args *pkap;
1166         struct pollfd *pfd;
1167         struct kevent *kev;
1168         int kev_count;
1169
1170         pkap = (struct poll_kevent_copyin_args *)arg;
1171
1172         while (pkap->pfds < pkap->nfds) {
1173                 pfd = &pkap->fds[pkap->pfds];
1174
1175                 /* Clear return events */
1176                 pfd->revents = 0;
1177
1178                 /* Do not check if fd is equal to -1 */
1179                 if (pfd->fd == -1) {
1180                         ++pkap->pfds;
1181                         continue;
1182                 }
1183
1184                 kev_count = 0;
1185                 if (pfd->events & (POLLIN | POLLRDNORM))
1186                         kev_count++;
1187                 if (pfd->events & (POLLOUT | POLLWRNORM))
1188                         kev_count++;
1189                 if (pfd->events & (POLLPRI | POLLRDBAND))
1190                         kev_count++;
1191
1192                 if (*events + kev_count > maxevents)
1193                         return (0);
1194
1195                 /*
1196                  * NOTE: A combined serial number and poll array index is
1197                  * stored in kev->udata.
1198                  */
1199                 kev = &kevp[*events];
1200                 if (pfd->events & (POLLIN | POLLRDNORM)) {
1201                         EV_SET(kev++, pfd->fd, EVFILT_READ, EV_ADD|EV_ENABLE,
1202                                0, 0, (void *)(pkap->lwp->lwp_kqueue_serial +
1203                                               pkap->pfds));
1204                 }
1205                 if (pfd->events & (POLLOUT | POLLWRNORM)) {
1206                         EV_SET(kev++, pfd->fd, EVFILT_WRITE, EV_ADD|EV_ENABLE,
1207                                0, 0, (void *)(pkap->lwp->lwp_kqueue_serial +
1208                                               pkap->pfds));
1209                 }
1210                 if (pfd->events & (POLLPRI | POLLRDBAND)) {
1211                         EV_SET(kev++, pfd->fd, EVFILT_EXCEPT, EV_ADD|EV_ENABLE,
1212                                NOTE_OOB, 0,
1213                                (void *)(pkap->lwp->lwp_kqueue_serial +
1214                                         pkap->pfds));
1215                 }
1216
1217                 if (nseldebug) {
1218                         kprintf("poll index %d fd %d events %08x\n",
1219                                 pkap->pfds, pfd->fd, pfd->events);
1220                 }
1221
1222                 ++pkap->pfds;
1223                 (*events) += kev_count;
1224         }
1225
1226         return (0);
1227 }
1228
1229 static int
1230 poll_copyout(void *arg, struct kevent *kevp, int count, int *res)
1231 {
1232         struct poll_kevent_copyin_args *pkap;
1233         struct pollfd *pfd;
1234         struct kevent kev;
1235         int i;
1236         u_int pi;
1237
1238         pkap = (struct poll_kevent_copyin_args *)arg;
1239
1240         for (i = 0; i < count; ++i) {
1241                 /*
1242                  * Extract the poll array index and delete spurious events.
1243                  * We can easily tell if the serial number is incorrect
1244                  * by checking whether the extracted index is out of range.
1245                  */
1246                 pi = (u_int)kevp[i].udata - (u_int)pkap->lwp->lwp_kqueue_serial;
1247
1248                 if (pi >= pkap->nfds) {
1249                         kev = kevp[i];
1250                         kev.flags = EV_DISABLE|EV_DELETE;
1251                         kqueue_register(&pkap->lwp->lwp_kqueue, &kev);
1252                         if (nseldebug)
1253                                 kprintf("poll index %d out of range\n", pi);
1254                         continue;
1255                 }
1256                 pfd = &pkap->fds[pi];
1257                 if (kevp[i].ident == pfd->fd) {
1258                         if (kevp[i].flags & EV_ERROR) {
1259                                 switch(kevp[i].data) {
1260                                 case EOPNOTSUPP:
1261                                         /*
1262                                          * Operation not supported.  Poll
1263                                          * does not return an error for
1264                                          * POLLPRI (OOB/urgent data) when
1265                                          * it is not supported by the device.
1266                                          */
1267                                         if (kevp[i].filter != EVFILT_EXCEPT) {
1268                                                 pfd->revents |= POLLERR;
1269                                                 ++*res;
1270                                         }
1271                                         break;
1272                                 case EBADF:
1273                                         /* Bad file descriptor */
1274                                         pfd->revents |= POLLNVAL;
1275                                         ++*res;
1276                                         break;
1277                                 default:
1278                                         pfd->revents |= POLLERR;
1279                                         ++*res;
1280                                         break;
1281                                 }
1282                                 if (nseldebug)
1283                                         kprintf("poll index %d fd %d filter %d error %d\n",
1284                                                 pi, pfd->fd,
1285                                                 kevp[i].filter, kevp[i].data);
1286                                 continue;
1287                         }
1288
1289                         if (kevp[i].flags & EV_EOF) {
1290                                 pfd->revents |= POLLHUP;
1291                                 ++*res;
1292                                 continue;
1293                         }
1294
1295                         switch (kevp[i].filter) {
1296                         case EVFILT_READ:
1297                                 pfd->revents |= (POLLIN | POLLRDNORM);
1298                                 break;
1299                         case EVFILT_WRITE:
1300                                 pfd->revents |= (POLLOUT | POLLWRNORM);
1301                                 break;
1302                         case EVFILT_EXCEPT:
1303                                 pfd->revents |= (POLLPRI | POLLRDBAND);
1304                                 break;
1305                         }
1306
1307                         if (nseldebug) {
1308                                 kprintf("poll index %d fd %d revents %08x\n",
1309                                         pi, pfd->fd, pfd->revents);
1310                         }
1311
1312                         ++*res;
1313                         continue;
1314                 } else {
1315                         if (nseldebug)
1316                                 kprintf("poll index %d mismatch %d/%d\n",
1317                                         pi, kevp[i].ident, pfd->fd);
1318                 }
1319         }
1320
1321         return (0);
1322 }
1323
1324 static int
1325 dopoll(int nfds, struct pollfd *fds, struct timespec *ts, int *res)
1326 {
1327         struct poll_kevent_copyin_args ka;
1328         struct pollfd sfds[64];
1329         int bytes;
1330         int error;
1331
1332         *res = 0;
1333         if (nfds < 0)
1334                 return (EINVAL);
1335
1336         /*
1337          * This is a bit arbitrary but we need to limit internal kmallocs.
1338          */
1339         if (nfds > maxfilesperproc * 2)
1340                 nfds = maxfilesperproc * 2;
1341         bytes = sizeof(struct pollfd) * nfds;
1342
1343         ka.lwp = curthread->td_lwp;
1344         ka.nfds = nfds;
1345         ka.pfds = 0;
1346         ka.error = 0;
1347
1348         if (ka.nfds < 64)
1349                 ka.fds = sfds;
1350         else
1351                 ka.fds = kmalloc(bytes, M_SELECT, M_WAITOK);
1352
1353         error = copyin(fds, ka.fds, bytes);
1354         if (error == 0)
1355                 error = kern_kevent(&ka.lwp->lwp_kqueue, ka.nfds, res, &ka,
1356                                     poll_copyin, poll_copyout, ts);
1357
1358         if (error == 0)
1359                 error = copyout(ka.fds, fds, bytes);
1360
1361         if (ka.fds != sfds)
1362                 kfree(ka.fds, M_SELECT);
1363
1364         ka.lwp->lwp_kqueue_serial += nfds;
1365
1366         return (error);
1367 }
1368
1369 static int
1370 socket_wait_copyin(void *arg, struct kevent *kevp, int maxevents, int *events)
1371 {
1372         return (0);
1373 }
1374
1375 static int
1376 socket_wait_copyout(void *arg, struct kevent *kevp, int count, int *res)
1377 {
1378         ++*res;
1379         return (0);
1380 }
1381
1382 extern  struct fileops socketops;
1383 int
1384 socket_wait(struct socket *so, struct timespec *ts, int *res)
1385 {
1386         struct file *fp;
1387         struct filedesc fd;
1388         struct kqueue kq;
1389         struct kevent kev;
1390         int error;
1391
1392         if ((error = falloc(NULL, &fp, NULL)) != 0)
1393                 return (error);
1394
1395         fp->f_ops = &socketops;
1396         fp->f_data = so;
1397         fsetfd(&fd, fp, 0);
1398
1399         kqueue_init(&kq, &fd);
1400
1401         EV_SET(&kev, 0, EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, NULL);
1402         if ((error = kqueue_register(&kq, &kev)) != 0) {
1403                 fdrop(fp);
1404                 return (error);
1405         }
1406
1407         error = kern_kevent(&kq, 1, res, NULL, socket_wait_copyin,
1408                             socket_wait_copyout, ts);
1409         fdrop(fp);
1410
1411         return (error);
1412 }
1413
1414 /*
1415  * OpenBSD poll system call.
1416  * XXX this isn't quite a true representation..  OpenBSD uses select ops.
1417  *
1418  * MPSAFE
1419  */
1420 int
1421 sys_openbsd_poll(struct openbsd_poll_args *uap)
1422 {
1423         return (sys_poll((struct poll_args *)uap));
1424 }
1425
1426 /*ARGSUSED*/
1427 int
1428 seltrue(cdev_t dev, int events)
1429 {
1430         return (events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
1431 }
1432
1433 /*
1434  * Record a select request.  A global wait must be used since a process/thread
1435  * might go away after recording its request.
1436  */
1437 void
1438 selrecord(struct thread *selector, struct selinfo *sip)
1439 {
1440         struct proc *p;
1441         struct lwp *lp = NULL;
1442
1443         if (selector->td_lwp == NULL)
1444                 panic("selrecord: thread needs a process");
1445
1446         if (sip->si_pid == selector->td_proc->p_pid &&
1447             sip->si_tid == selector->td_lwp->lwp_tid)
1448                 return;
1449         if (sip->si_pid && (p = pfind(sip->si_pid)))
1450                 lp = lwp_rb_tree_RB_LOOKUP(&p->p_lwp_tree, sip->si_tid);
1451         if (lp != NULL && lp->lwp_wchan == (caddr_t)&selwait) {
1452                 sip->si_flags |= SI_COLL;
1453         } else {
1454                 sip->si_pid = selector->td_proc->p_pid;
1455                 sip->si_tid = selector->td_lwp->lwp_tid;
1456         }
1457 }
1458
1459 /*
1460  * Do a wakeup when a selectable event occurs.
1461  */
1462 void
1463 selwakeup(struct selinfo *sip)
1464 {
1465         struct proc *p;
1466         struct lwp *lp = NULL;
1467
1468         if (sip->si_pid == 0)
1469                 return;
1470         if (sip->si_flags & SI_COLL) {
1471                 nselcoll++;
1472                 sip->si_flags &= ~SI_COLL;
1473                 wakeup((caddr_t)&selwait);      /* YYY fixable */
1474         }
1475         p = pfind(sip->si_pid);
1476         sip->si_pid = 0;
1477         if (p == NULL)
1478                 return;
1479         lp = lwp_rb_tree_RB_LOOKUP(&p->p_lwp_tree, sip->si_tid);
1480         if (lp == NULL)
1481                 return;
1482
1483         /*
1484          * This is a temporary hack until the code can be rewritten.
1485          * Check LWP_SELECT before assuming we can setrunnable().
1486          * Otherwise we might catch the lwp before it actually goes to
1487          * sleep.
1488          */
1489         crit_enter();
1490         if (lp->lwp_flag & LWP_SELECT) {
1491                 lp->lwp_flag &= ~LWP_SELECT;
1492         } else if (lp->lwp_wchan == (caddr_t)&selwait) {
1493                 /*
1494                  * Flag the process to break the tsleep when
1495                  * setrunnable is called, but only call setrunnable
1496                  * here if the process is not in a stopped state.
1497                  */
1498                 lp->lwp_flag |= LWP_BREAKTSLEEP;
1499                 if (p->p_stat != SSTOP)
1500                         setrunnable(lp);
1501         }
1502         crit_exit();
1503
1504         kqueue_wakeup(&lp->lwp_kqueue);
1505 }
1506