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