source: rtems-libbsd/freebsd/sys/kern/sys_generic.c @ f2cb584

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since f2cb584 was f2cb584, checked in by Sebastian Huber <sebastian.huber@…>, on 04/30/15 at 08:59:30

Update rtems_bsd_force_select_timeout()

  • Property mode set to 100644
File size: 42.3 KB
Line 
1#include <machine/rtems-bsd-kernel-space.h>
2
3/*-
4 * Copyright (c) 1982, 1986, 1989, 1993
5 *      The Regents of the University of California.  All rights reserved.
6 * (c) UNIX System Laboratories, Inc.
7 * All or some portions of this file are derived from material licensed
8 * to the University of California by American Telephone and Telegraph
9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
10 * the permission of UNIX System Laboratories, Inc.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 *    notice, this list of conditions and the following disclaimer in the
19 *    documentation and/or other materials provided with the distribution.
20 * 4. Neither the name of the University nor the names of its contributors
21 *    may be used to endorse or promote products derived from this software
22 *    without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 *      @(#)sys_generic.c       8.5 (Berkeley) 1/21/94
37 */
38
39#include <sys/cdefs.h>
40__FBSDID("$FreeBSD$");
41
42#include <rtems/bsd/local/opt_capsicum.h>
43#include <rtems/bsd/local/opt_compat.h>
44#include <rtems/bsd/local/opt_ktrace.h>
45
46#include <rtems/bsd/sys/param.h>
47#include <sys/systm.h>
48#include <sys/sysproto.h>
49#include <sys/capability.h>
50#include <sys/filedesc.h>
51#include <sys/filio.h>
52#include <sys/fcntl.h>
53#include <sys/file.h>
54#include <sys/proc.h>
55#include <sys/signalvar.h>
56#include <sys/socketvar.h>
57#include <sys/uio.h>
58#include <sys/kernel.h>
59#include <sys/ktr.h>
60#include <sys/limits.h>
61#include <sys/malloc.h>
62#include <sys/poll.h>
63#include <sys/resourcevar.h>
64#include <sys/selinfo.h>
65#include <sys/sleepqueue.h>
66#include <sys/syscallsubr.h>
67#include <sys/sysctl.h>
68#include <sys/sysent.h>
69#include <sys/vnode.h>
70#include <sys/bio.h>
71#include <sys/buf.h>
72#include <sys/condvar.h>
73#ifdef KTRACE
74#include <sys/ktrace.h>
75#endif
76
77#include <security/audit/audit.h>
78#ifdef __rtems__
79#include <machine/rtems-bsd-syscall-api.h>
80#endif /* __rtems__ */
81
82/*
83 * The following macro defines how many bytes will be allocated from
84 * the stack instead of memory allocated when passing the IOCTL data
85 * structures from userspace and to the kernel. Some IOCTLs having
86 * small data structures are used very frequently and this small
87 * buffer on the stack gives a significant speedup improvement for
88 * those requests. The value of this define should be greater or equal
89 * to 64 bytes and should also be power of two. The data structure is
90 * currently hard-aligned to a 8-byte boundary on the stack. This
91 * should currently be sufficient for all supported platforms.
92 */
93#define SYS_IOCTL_SMALL_SIZE    128     /* bytes */
94#define SYS_IOCTL_SMALL_ALIGN   8       /* bytes */
95
96#ifndef __rtems__
97int iosize_max_clamp = 1;
98SYSCTL_INT(_debug, OID_AUTO, iosize_max_clamp, CTLFLAG_RW,
99    &iosize_max_clamp, 0, "Clamp max i/o size to INT_MAX");
100int devfs_iosize_max_clamp = 1;
101SYSCTL_INT(_debug, OID_AUTO, devfs_iosize_max_clamp, CTLFLAG_RW,
102    &devfs_iosize_max_clamp, 0, "Clamp max i/o size to INT_MAX for devices");
103
104/*
105 * Assert that the return value of read(2) and write(2) syscalls fits
106 * into a register.  If not, an architecture will need to provide the
107 * usermode wrappers to reconstruct the result.
108 */
109CTASSERT(sizeof(register_t) >= sizeof(size_t));
110
111static MALLOC_DEFINE(M_IOCTLOPS, "ioctlops", "ioctl data buffer");
112#endif /* __rtems__ */
113static MALLOC_DEFINE(M_SELECT, "select", "select() buffer");
114#ifndef __rtems__
115MALLOC_DEFINE(M_IOV, "iov", "large iov's");
116#endif /* __rtems__ */
117
118static int      pollout(struct thread *, struct pollfd *, struct pollfd *,
119                    u_int);
120static int      pollscan(struct thread *, struct pollfd *, u_int);
121static int      pollrescan(struct thread *);
122static int      selscan(struct thread *, fd_mask **, fd_mask **, int);
123static int      selrescan(struct thread *, fd_mask **, fd_mask **);
124static void     selfdalloc(struct thread *, void *);
125static void     selfdfree(struct seltd *, struct selfd *);
126#ifndef __rtems__
127static int      dofileread(struct thread *, int, struct file *, struct uio *,
128                    off_t, int);
129static int      dofilewrite(struct thread *, int, struct file *, struct uio *,
130                    off_t, int);
131#endif /* __rtems__ */
132static void     doselwakeup(struct selinfo *, int);
133static void     seltdinit(struct thread *);
134static int      seltdwait(struct thread *, int);
135static void     seltdclear(struct thread *);
136
137/*
138 * One seltd per-thread allocated on demand as needed.
139 *
140 *      t - protected by st_mtx
141 *      k - Only accessed by curthread or read-only
142 */
143struct seltd {
144        STAILQ_HEAD(, selfd)    st_selq;        /* (k) List of selfds. */
145        struct selfd            *st_free1;      /* (k) free fd for read set. */
146        struct selfd            *st_free2;      /* (k) free fd for write set. */
147        struct mtx              st_mtx;         /* Protects struct seltd */
148        struct cv               st_wait;        /* (t) Wait channel. */
149        int                     st_flags;       /* (t) SELTD_ flags. */
150};
151
152#define SELTD_PENDING   0x0001                  /* We have pending events. */
153#define SELTD_RESCAN    0x0002                  /* Doing a rescan. */
154
155/*
156 * One selfd allocated per-thread per-file-descriptor.
157 *      f - protected by sf_mtx
158 */
159struct selfd {
160        STAILQ_ENTRY(selfd)     sf_link;        /* (k) fds owned by this td. */
161        TAILQ_ENTRY(selfd)      sf_threads;     /* (f) fds on this selinfo. */
162        struct selinfo          *sf_si;         /* (f) selinfo when linked. */
163        struct mtx              *sf_mtx;        /* Pointer to selinfo mtx. */
164        struct seltd            *sf_td;         /* (k) owning seltd. */
165        void                    *sf_cookie;     /* (k) fd or pollfd. */
166};
167
168static uma_zone_t selfd_zone;
169static struct mtx_pool *mtxpool_select;
170
171#ifndef __rtems__
172#ifndef _SYS_SYSPROTO_H_
173struct read_args {
174        int     fd;
175        void    *buf;
176        size_t  nbyte;
177};
178#endif
179int
180sys_read(td, uap)
181        struct thread *td;
182        struct read_args *uap;
183{
184        struct uio auio;
185        struct iovec aiov;
186        int error;
187
188        if (uap->nbyte > IOSIZE_MAX)
189                return (EINVAL);
190        aiov.iov_base = uap->buf;
191        aiov.iov_len = uap->nbyte;
192        auio.uio_iov = &aiov;
193        auio.uio_iovcnt = 1;
194        auio.uio_resid = uap->nbyte;
195        auio.uio_segflg = UIO_USERSPACE;
196        error = kern_readv(td, uap->fd, &auio);
197        return(error);
198}
199
200/*
201 * Positioned read system call
202 */
203#ifndef _SYS_SYSPROTO_H_
204struct pread_args {
205        int     fd;
206        void    *buf;
207        size_t  nbyte;
208        int     pad;
209        off_t   offset;
210};
211#endif
212int
213sys_pread(td, uap)
214        struct thread *td;
215        struct pread_args *uap;
216{
217        struct uio auio;
218        struct iovec aiov;
219        int error;
220
221        if (uap->nbyte > IOSIZE_MAX)
222                return (EINVAL);
223        aiov.iov_base = uap->buf;
224        aiov.iov_len = uap->nbyte;
225        auio.uio_iov = &aiov;
226        auio.uio_iovcnt = 1;
227        auio.uio_resid = uap->nbyte;
228        auio.uio_segflg = UIO_USERSPACE;
229        error = kern_preadv(td, uap->fd, &auio, uap->offset);
230        return(error);
231}
232
233int
234freebsd6_pread(td, uap)
235        struct thread *td;
236        struct freebsd6_pread_args *uap;
237{
238        struct pread_args oargs;
239
240        oargs.fd = uap->fd;
241        oargs.buf = uap->buf;
242        oargs.nbyte = uap->nbyte;
243        oargs.offset = uap->offset;
244        return (sys_pread(td, &oargs));
245}
246
247/*
248 * Scatter read system call.
249 */
250#ifndef _SYS_SYSPROTO_H_
251struct readv_args {
252        int     fd;
253        struct  iovec *iovp;
254        u_int   iovcnt;
255};
256#endif
257int
258sys_readv(struct thread *td, struct readv_args *uap)
259{
260        struct uio *auio;
261        int error;
262
263        error = copyinuio(uap->iovp, uap->iovcnt, &auio);
264        if (error)
265                return (error);
266        error = kern_readv(td, uap->fd, auio);
267        free(auio, M_IOV);
268        return (error);
269}
270
271int
272kern_readv(struct thread *td, int fd, struct uio *auio)
273{
274        struct file *fp;
275        int error;
276
277        error = fget_read(td, fd, CAP_READ | CAP_SEEK, &fp);
278        if (error)
279                return (error);
280        error = dofileread(td, fd, fp, auio, (off_t)-1, 0);
281        fdrop(fp, td);
282        return (error);
283}
284
285/*
286 * Scatter positioned read system call.
287 */
288#ifndef _SYS_SYSPROTO_H_
289struct preadv_args {
290        int     fd;
291        struct  iovec *iovp;
292        u_int   iovcnt;
293        off_t   offset;
294};
295#endif
296int
297sys_preadv(struct thread *td, struct preadv_args *uap)
298{
299        struct uio *auio;
300        int error;
301
302        error = copyinuio(uap->iovp, uap->iovcnt, &auio);
303        if (error)
304                return (error);
305        error = kern_preadv(td, uap->fd, auio, uap->offset);
306        free(auio, M_IOV);
307        return (error);
308}
309
310int
311kern_preadv(td, fd, auio, offset)
312        struct thread *td;
313        int fd;
314        struct uio *auio;
315        off_t offset;
316{
317        struct file *fp;
318        int error;
319
320        error = fget_read(td, fd, CAP_READ, &fp);
321        if (error)
322                return (error);
323        if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE))
324                error = ESPIPE;
325        else if (offset < 0 && fp->f_vnode->v_type != VCHR)
326                error = EINVAL;
327        else
328                error = dofileread(td, fd, fp, auio, offset, FOF_OFFSET);
329        fdrop(fp, td);
330        return (error);
331}
332
333/*
334 * Common code for readv and preadv that reads data in
335 * from a file using the passed in uio, offset, and flags.
336 */
337static int
338dofileread(td, fd, fp, auio, offset, flags)
339        struct thread *td;
340        int fd;
341        struct file *fp;
342        struct uio *auio;
343        off_t offset;
344        int flags;
345{
346        ssize_t cnt;
347        int error;
348#ifdef KTRACE
349        struct uio *ktruio = NULL;
350#endif
351
352        /* Finish zero length reads right here */
353        if (auio->uio_resid == 0) {
354                td->td_retval[0] = 0;
355                return(0);
356        }
357        auio->uio_rw = UIO_READ;
358        auio->uio_offset = offset;
359        auio->uio_td = td;
360#ifdef KTRACE
361        if (KTRPOINT(td, KTR_GENIO))
362                ktruio = cloneuio(auio);
363#endif
364        cnt = auio->uio_resid;
365        if ((error = fo_read(fp, auio, td->td_ucred, flags, td))) {
366                if (auio->uio_resid != cnt && (error == ERESTART ||
367                    error == EINTR || error == EWOULDBLOCK))
368                        error = 0;
369        }
370        cnt -= auio->uio_resid;
371#ifdef KTRACE
372        if (ktruio != NULL) {
373                ktruio->uio_resid = cnt;
374                ktrgenio(fd, UIO_READ, ktruio, error);
375        }
376#endif
377        td->td_retval[0] = cnt;
378        return (error);
379}
380
381#ifndef _SYS_SYSPROTO_H_
382struct write_args {
383        int     fd;
384        const void *buf;
385        size_t  nbyte;
386};
387#endif
388int
389sys_write(td, uap)
390        struct thread *td;
391        struct write_args *uap;
392{
393        struct uio auio;
394        struct iovec aiov;
395        int error;
396
397        if (uap->nbyte > IOSIZE_MAX)
398                return (EINVAL);
399        aiov.iov_base = (void *)(uintptr_t)uap->buf;
400        aiov.iov_len = uap->nbyte;
401        auio.uio_iov = &aiov;
402        auio.uio_iovcnt = 1;
403        auio.uio_resid = uap->nbyte;
404        auio.uio_segflg = UIO_USERSPACE;
405        error = kern_writev(td, uap->fd, &auio);
406        return(error);
407}
408
409/*
410 * Positioned write system call.
411 */
412#ifndef _SYS_SYSPROTO_H_
413struct pwrite_args {
414        int     fd;
415        const void *buf;
416        size_t  nbyte;
417        int     pad;
418        off_t   offset;
419};
420#endif
421int
422sys_pwrite(td, uap)
423        struct thread *td;
424        struct pwrite_args *uap;
425{
426        struct uio auio;
427        struct iovec aiov;
428        int error;
429
430        if (uap->nbyte > IOSIZE_MAX)
431                return (EINVAL);
432        aiov.iov_base = (void *)(uintptr_t)uap->buf;
433        aiov.iov_len = uap->nbyte;
434        auio.uio_iov = &aiov;
435        auio.uio_iovcnt = 1;
436        auio.uio_resid = uap->nbyte;
437        auio.uio_segflg = UIO_USERSPACE;
438        error = kern_pwritev(td, uap->fd, &auio, uap->offset);
439        return(error);
440}
441
442int
443freebsd6_pwrite(td, uap)
444        struct thread *td;
445        struct freebsd6_pwrite_args *uap;
446{
447        struct pwrite_args oargs;
448
449        oargs.fd = uap->fd;
450        oargs.buf = uap->buf;
451        oargs.nbyte = uap->nbyte;
452        oargs.offset = uap->offset;
453        return (sys_pwrite(td, &oargs));
454}
455
456/*
457 * Gather write system call.
458 */
459#ifndef _SYS_SYSPROTO_H_
460struct writev_args {
461        int     fd;
462        struct  iovec *iovp;
463        u_int   iovcnt;
464};
465#endif
466int
467sys_writev(struct thread *td, struct writev_args *uap)
468{
469        struct uio *auio;
470        int error;
471
472        error = copyinuio(uap->iovp, uap->iovcnt, &auio);
473        if (error)
474                return (error);
475        error = kern_writev(td, uap->fd, auio);
476        free(auio, M_IOV);
477        return (error);
478}
479
480int
481kern_writev(struct thread *td, int fd, struct uio *auio)
482{
483        struct file *fp;
484        int error;
485
486        error = fget_write(td, fd, CAP_WRITE | CAP_SEEK, &fp);
487        if (error)
488                return (error);
489        error = dofilewrite(td, fd, fp, auio, (off_t)-1, 0);
490        fdrop(fp, td);
491        return (error);
492}
493
494/*
495 * Gather positioned write system call.
496 */
497#ifndef _SYS_SYSPROTO_H_
498struct pwritev_args {
499        int     fd;
500        struct  iovec *iovp;
501        u_int   iovcnt;
502        off_t   offset;
503};
504#endif
505int
506sys_pwritev(struct thread *td, struct pwritev_args *uap)
507{
508        struct uio *auio;
509        int error;
510
511        error = copyinuio(uap->iovp, uap->iovcnt, &auio);
512        if (error)
513                return (error);
514        error = kern_pwritev(td, uap->fd, auio, uap->offset);
515        free(auio, M_IOV);
516        return (error);
517}
518
519int
520kern_pwritev(td, fd, auio, offset)
521        struct thread *td;
522        struct uio *auio;
523        int fd;
524        off_t offset;
525{
526        struct file *fp;
527        int error;
528
529        error = fget_write(td, fd, CAP_WRITE, &fp);
530        if (error)
531                return (error);
532        if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE))
533                error = ESPIPE;
534        else if (offset < 0 && fp->f_vnode->v_type != VCHR)
535                error = EINVAL;
536        else
537                error = dofilewrite(td, fd, fp, auio, offset, FOF_OFFSET);
538        fdrop(fp, td);
539        return (error);
540}
541
542/*
543 * Common code for writev and pwritev that writes data to
544 * a file using the passed in uio, offset, and flags.
545 */
546static int
547dofilewrite(td, fd, fp, auio, offset, flags)
548        struct thread *td;
549        int fd;
550        struct file *fp;
551        struct uio *auio;
552        off_t offset;
553        int flags;
554{
555        ssize_t cnt;
556        int error;
557#ifdef KTRACE
558        struct uio *ktruio = NULL;
559#endif
560
561        auio->uio_rw = UIO_WRITE;
562        auio->uio_td = td;
563        auio->uio_offset = offset;
564#ifdef KTRACE
565        if (KTRPOINT(td, KTR_GENIO))
566                ktruio = cloneuio(auio);
567#endif
568        cnt = auio->uio_resid;
569        if (fp->f_type == DTYPE_VNODE &&
570            (fp->f_vnread_flags & FDEVFS_VNODE) == 0)
571                bwillwrite();
572        if ((error = fo_write(fp, auio, td->td_ucred, flags, td))) {
573                if (auio->uio_resid != cnt && (error == ERESTART ||
574                    error == EINTR || error == EWOULDBLOCK))
575                        error = 0;
576                /* Socket layer is responsible for issuing SIGPIPE. */
577                if (fp->f_type != DTYPE_SOCKET && error == EPIPE) {
578                        PROC_LOCK(td->td_proc);
579                        tdsignal(td, SIGPIPE);
580                        PROC_UNLOCK(td->td_proc);
581                }
582        }
583        cnt -= auio->uio_resid;
584#ifdef KTRACE
585        if (ktruio != NULL) {
586                ktruio->uio_resid = cnt;
587                ktrgenio(fd, UIO_WRITE, ktruio, error);
588        }
589#endif
590        td->td_retval[0] = cnt;
591        return (error);
592}
593
594/*
595 * Truncate a file given a file descriptor.
596 *
597 * Can't use fget_write() here, since must return EINVAL and not EBADF if the
598 * descriptor isn't writable.
599 */
600int
601kern_ftruncate(td, fd, length)
602        struct thread *td;
603        int fd;
604        off_t length;
605{
606        struct file *fp;
607        int error;
608
609        AUDIT_ARG_FD(fd);
610        if (length < 0)
611                return (EINVAL);
612        error = fget(td, fd, CAP_FTRUNCATE, &fp);
613        if (error)
614                return (error);
615        AUDIT_ARG_FILE(td->td_proc, fp);
616        if (!(fp->f_flag & FWRITE)) {
617                fdrop(fp, td);
618                return (EINVAL);
619        }
620        error = fo_truncate(fp, length, td->td_ucred, td);
621        fdrop(fp, td);
622        return (error);
623}
624
625#ifndef _SYS_SYSPROTO_H_
626struct ftruncate_args {
627        int     fd;
628        int     pad;
629        off_t   length;
630};
631#endif
632int
633sys_ftruncate(td, uap)
634        struct thread *td;
635        struct ftruncate_args *uap;
636{
637
638        return (kern_ftruncate(td, uap->fd, uap->length));
639}
640
641#if defined(COMPAT_43)
642#ifndef _SYS_SYSPROTO_H_
643struct oftruncate_args {
644        int     fd;
645        long    length;
646};
647#endif
648int
649oftruncate(td, uap)
650        struct thread *td;
651        struct oftruncate_args *uap;
652{
653
654        return (kern_ftruncate(td, uap->fd, uap->length));
655}
656#endif /* COMPAT_43 */
657
658#ifndef _SYS_SYSPROTO_H_
659struct ioctl_args {
660        int     fd;
661        u_long  com;
662        caddr_t data;
663};
664#endif
665/* ARGSUSED */
666int
667sys_ioctl(struct thread *td, struct ioctl_args *uap)
668{
669        u_char smalldata[SYS_IOCTL_SMALL_SIZE] __aligned(SYS_IOCTL_SMALL_ALIGN);
670        u_long com;
671        int arg, error;
672        u_int size;
673        caddr_t data;
674
675        if (uap->com > 0xffffffff) {
676                printf(
677                    "WARNING pid %d (%s): ioctl sign-extension ioctl %lx\n",
678                    td->td_proc->p_pid, td->td_name, uap->com);
679                uap->com &= 0xffffffff;
680        }
681        com = uap->com;
682
683        /*
684         * Interpret high order word to find amount of data to be
685         * copied to/from the user's address space.
686         */
687        size = IOCPARM_LEN(com);
688        if ((size > IOCPARM_MAX) ||
689            ((com & (IOC_VOID  | IOC_IN | IOC_OUT)) == 0) ||
690#if defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
691            ((com & IOC_OUT) && size == 0) ||
692#else
693            ((com & (IOC_IN | IOC_OUT)) && size == 0) ||
694#endif
695            ((com & IOC_VOID) && size > 0 && size != sizeof(int)))
696                return (ENOTTY);
697
698        if (size > 0) {
699                if (com & IOC_VOID) {
700                        /* Integer argument. */
701                        arg = (intptr_t)uap->data;
702                        data = (void *)&arg;
703                        size = 0;
704                } else {
705                        if (size > SYS_IOCTL_SMALL_SIZE)
706                                data = malloc((u_long)size, M_IOCTLOPS, M_WAITOK);
707                        else
708                                data = smalldata;
709                }
710        } else
711                data = (void *)&uap->data;
712        if (com & IOC_IN) {
713                error = copyin(uap->data, data, (u_int)size);
714                if (error != 0)
715                        goto out;
716        } else if (com & IOC_OUT) {
717                /*
718                 * Zero the buffer so the user always
719                 * gets back something deterministic.
720                 */
721                bzero(data, size);
722        }
723
724        error = kern_ioctl(td, uap->fd, com, data);
725
726        if (error == 0 && (com & IOC_OUT))
727                error = copyout(data, uap->data, (u_int)size);
728
729out:
730        if (size > SYS_IOCTL_SMALL_SIZE)
731                free(data, M_IOCTLOPS);
732        return (error);
733}
734
735int
736kern_ioctl(struct thread *td, int fd, u_long com, caddr_t data)
737{
738        struct file *fp;
739        struct filedesc *fdp;
740        int error;
741        int tmp;
742
743        AUDIT_ARG_FD(fd);
744        AUDIT_ARG_CMD(com);
745        if ((error = fget(td, fd, CAP_IOCTL, &fp)) != 0)
746                return (error);
747        if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
748                fdrop(fp, td);
749                return (EBADF);
750        }
751        fdp = td->td_proc->p_fd;
752        switch (com) {
753        case FIONCLEX:
754                FILEDESC_XLOCK(fdp);
755                fdp->fd_ofileflags[fd] &= ~UF_EXCLOSE;
756                FILEDESC_XUNLOCK(fdp);
757                goto out;
758        case FIOCLEX:
759                FILEDESC_XLOCK(fdp);
760                fdp->fd_ofileflags[fd] |= UF_EXCLOSE;
761                FILEDESC_XUNLOCK(fdp);
762                goto out;
763        case FIONBIO:
764                if ((tmp = *(int *)data))
765                        atomic_set_int(&fp->f_flag, FNONBLOCK);
766                else
767                        atomic_clear_int(&fp->f_flag, FNONBLOCK);
768                data = (void *)&tmp;
769                break;
770        case FIOASYNC:
771                if ((tmp = *(int *)data))
772                        atomic_set_int(&fp->f_flag, FASYNC);
773                else
774                        atomic_clear_int(&fp->f_flag, FASYNC);
775                data = (void *)&tmp;
776                break;
777        }
778
779        error = fo_ioctl(fp, com, data, td->td_ucred, td);
780out:
781        fdrop(fp, td);
782        return (error);
783}
784
785int
786poll_no_poll(int events)
787{
788        /*
789         * Return true for read/write.  If the user asked for something
790         * special, return POLLNVAL, so that clients have a way of
791         * determining reliably whether or not the extended
792         * functionality is present without hard-coding knowledge
793         * of specific filesystem implementations.
794         */
795        if (events & ~POLLSTANDARD)
796                return (POLLNVAL);
797
798        return (events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
799}
800
801int
802sys_pselect(struct thread *td, struct pselect_args *uap)
803{
804        struct timespec ts;
805        struct timeval tv, *tvp;
806        sigset_t set, *uset;
807        int error;
808
809        if (uap->ts != NULL) {
810                error = copyin(uap->ts, &ts, sizeof(ts));
811                if (error != 0)
812                    return (error);
813                TIMESPEC_TO_TIMEVAL(&tv, &ts);
814                tvp = &tv;
815        } else
816                tvp = NULL;
817        if (uap->sm != NULL) {
818                error = copyin(uap->sm, &set, sizeof(set));
819                if (error != 0)
820                        return (error);
821                uset = &set;
822        } else
823                uset = NULL;
824        return (kern_pselect(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,
825            uset, NFDBITS));
826}
827
828int
829kern_pselect(struct thread *td, int nd, fd_set *in, fd_set *ou, fd_set *ex,
830    struct timeval *tvp, sigset_t *uset, int abi_nfdbits)
831{
832        int error;
833
834        if (uset != NULL) {
835                error = kern_sigprocmask(td, SIG_SETMASK, uset,
836                    &td->td_oldsigmask, 0);
837                if (error != 0)
838                        return (error);
839                td->td_pflags |= TDP_OLDMASK;
840                /*
841                 * Make sure that ast() is called on return to
842                 * usermode and TDP_OLDMASK is cleared, restoring old
843                 * sigmask.
844                 */
845                thread_lock(td);
846                td->td_flags |= TDF_ASTPENDING;
847                thread_unlock(td);
848        }
849        error = kern_select(td, nd, in, ou, ex, tvp, abi_nfdbits);
850        return (error);
851}
852
853#ifndef _SYS_SYSPROTO_H_
854struct select_args {
855        int     nd;
856        fd_set  *in, *ou, *ex;
857        struct  timeval *tv;
858};
859#endif
860int
861sys_select(struct thread *td, struct select_args *uap)
862{
863        struct timeval tv, *tvp;
864        int error;
865
866        if (uap->tv != NULL) {
867                error = copyin(uap->tv, &tv, sizeof(tv));
868                if (error)
869                        return (error);
870                tvp = &tv;
871        } else
872                tvp = NULL;
873
874        return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,
875            NFDBITS));
876}
877#endif /* __rtems__ */
878
879/*
880 * In the unlikely case when user specified n greater then the last
881 * open file descriptor, check that no bits are set after the last
882 * valid fd.  We must return EBADF if any is set.
883 *
884 * There are applications that rely on the behaviour.
885 *
886 * nd is fd_lastfile + 1.
887 */
888static int
889select_check_badfd(fd_set *fd_in, int nd, int ndu, int abi_nfdbits)
890{
891        char *addr, *oaddr;
892        int b, i, res;
893        uint8_t bits;
894
895        if (nd >= ndu || fd_in == NULL)
896                return (0);
897
898        oaddr = NULL;
899        bits = 0; /* silence gcc */
900        for (i = nd; i < ndu; i++) {
901                b = i / NBBY;
902#if BYTE_ORDER == LITTLE_ENDIAN
903                addr = (char *)fd_in + b;
904#else
905                addr = (char *)fd_in;
906                if (abi_nfdbits == NFDBITS) {
907                        addr += rounddown(b, sizeof(fd_mask)) +
908                            sizeof(fd_mask) - 1 - b % sizeof(fd_mask);
909                } else {
910                        addr += rounddown(b, sizeof(uint32_t)) +
911                            sizeof(uint32_t) - 1 - b % sizeof(uint32_t);
912                }
913#endif
914                if (addr != oaddr) {
915                        res = fubyte(addr);
916                        if (res == -1)
917                                return (EFAULT);
918                        oaddr = addr;
919                        bits = res;
920                }
921                if ((bits & (1 << (i % NBBY))) != 0)
922                        return (EBADF);
923        }
924        return (0);
925}
926
927int
928kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
929    fd_set *fd_ex, struct timeval *tvp, int abi_nfdbits)
930{
931        struct filedesc *fdp;
932        /*
933         * The magic 2048 here is chosen to be just enough for FD_SETSIZE
934         * infds with the new FD_SETSIZE of 1024, and more than enough for
935         * FD_SETSIZE infds, outfds and exceptfds with the old FD_SETSIZE
936         * of 256.
937         */
938        fd_mask s_selbits[howmany(2048, NFDBITS)];
939        fd_mask *ibits[3], *obits[3], *selbits, *sbp;
940        struct timeval atv, rtv, ttv;
941        int error, lf, ndu, timo;
942        u_int nbufbytes, ncpbytes, ncpubytes, nfdbits;
943
944        if (nd < 0)
945                return (EINVAL);
946#ifndef __rtems__
947        fdp = td->td_proc->p_fd;
948#endif /* __rtems__ */
949        ndu = nd;
950#ifndef __rtems__
951        lf = fdp->fd_lastfile;
952#else /* __rtems__ */
953        (void) fdp;
954        lf = rtems_libio_number_iops;
955#endif /* __rtems__ */
956        if (nd > lf + 1)
957                nd = lf + 1;
958
959        error = select_check_badfd(fd_in, nd, ndu, abi_nfdbits);
960        if (error != 0)
961                return (error);
962        error = select_check_badfd(fd_ou, nd, ndu, abi_nfdbits);
963        if (error != 0)
964                return (error);
965        error = select_check_badfd(fd_ex, nd, ndu, abi_nfdbits);
966        if (error != 0)
967                return (error);
968
969        /*
970         * Allocate just enough bits for the non-null fd_sets.  Use the
971         * preallocated auto buffer if possible.
972         */
973        nfdbits = roundup(nd, NFDBITS);
974        ncpbytes = nfdbits / NBBY;
975        ncpubytes = roundup(nd, abi_nfdbits) / NBBY;
976        nbufbytes = 0;
977        if (fd_in != NULL)
978                nbufbytes += 2 * ncpbytes;
979        if (fd_ou != NULL)
980                nbufbytes += 2 * ncpbytes;
981        if (fd_ex != NULL)
982                nbufbytes += 2 * ncpbytes;
983        if (nbufbytes <= sizeof s_selbits)
984                selbits = &s_selbits[0];
985        else
986                selbits = malloc(nbufbytes, M_SELECT, M_WAITOK);
987
988        /*
989         * Assign pointers into the bit buffers and fetch the input bits.
990         * Put the output buffers together so that they can be bzeroed
991         * together.
992         */
993        sbp = selbits;
994#define getbits(name, x) \
995        do {                                                            \
996                if (name == NULL) {                                     \
997                        ibits[x] = NULL;                                \
998                        obits[x] = NULL;                                \
999                } else {                                                \
1000                        ibits[x] = sbp + nbufbytes / 2 / sizeof *sbp;   \
1001                        obits[x] = sbp;                                 \
1002                        sbp += ncpbytes / sizeof *sbp;                  \
1003                        error = copyin(name, ibits[x], ncpubytes);      \
1004                        if (error != 0)                                 \
1005                                goto done;                              \
1006                        bzero((char *)ibits[x] + ncpubytes,             \
1007                            ncpbytes - ncpubytes);                      \
1008                }                                                       \
1009        } while (0)
1010        getbits(fd_in, 0);
1011        getbits(fd_ou, 1);
1012        getbits(fd_ex, 2);
1013#undef  getbits
1014
1015#if BYTE_ORDER == BIG_ENDIAN && defined(__LP64__)
1016        /*
1017         * XXX: swizzle_fdset assumes that if abi_nfdbits != NFDBITS,
1018         * we are running under 32-bit emulation. This should be more
1019         * generic.
1020         */
1021#define swizzle_fdset(bits)                                             \
1022        if (abi_nfdbits != NFDBITS && bits != NULL) {                   \
1023                int i;                                                  \
1024                for (i = 0; i < ncpbytes / sizeof *sbp; i++)            \
1025                        bits[i] = (bits[i] >> 32) | (bits[i] << 32);    \
1026        }
1027#else
1028#define swizzle_fdset(bits)
1029#endif
1030
1031        /* Make sure the bit order makes it through an ABI transition */
1032        swizzle_fdset(ibits[0]);
1033        swizzle_fdset(ibits[1]);
1034        swizzle_fdset(ibits[2]);
1035       
1036        if (nbufbytes != 0)
1037                bzero(selbits, nbufbytes / 2);
1038
1039        if (tvp != NULL) {
1040                atv = *tvp;
1041                if (itimerfix(&atv)) {
1042                        error = EINVAL;
1043                        goto done;
1044                }
1045                getmicrouptime(&rtv);
1046                timevaladd(&atv, &rtv);
1047        } else {
1048                atv.tv_sec = 0;
1049                atv.tv_usec = 0;
1050        }
1051        timo = 0;
1052        seltdinit(td);
1053        /* Iterate until the timeout expires or descriptors become ready. */
1054        for (;;) {
1055                error = selscan(td, ibits, obits, nd);
1056                if (error || td->td_retval[0] != 0)
1057                        break;
1058                if (atv.tv_sec || atv.tv_usec) {
1059                        getmicrouptime(&rtv);
1060                        if (timevalcmp(&rtv, &atv, >=))
1061                                break;
1062                        ttv = atv;
1063                        timevalsub(&ttv, &rtv);
1064                        timo = ttv.tv_sec > 24 * 60 * 60 ?
1065                            24 * 60 * 60 * hz : tvtohz(&ttv);
1066                }
1067                error = seltdwait(td, timo);
1068                if (error)
1069                        break;
1070                error = selrescan(td, ibits, obits);
1071                if (error || td->td_retval[0] != 0)
1072                        break;
1073        }
1074        seltdclear(td);
1075
1076done:
1077        /* select is not restarted after signals... */
1078        if (error == ERESTART)
1079                error = EINTR;
1080        if (error == EWOULDBLOCK)
1081                error = 0;
1082
1083        /* swizzle bit order back, if necessary */
1084        swizzle_fdset(obits[0]);
1085        swizzle_fdset(obits[1]);
1086        swizzle_fdset(obits[2]);
1087#undef swizzle_fdset
1088
1089#define putbits(name, x) \
1090        if (name && (error2 = copyout(obits[x], name, ncpubytes))) \
1091                error = error2;
1092        if (error == 0) {
1093                int error2;
1094
1095                putbits(fd_in, 0);
1096                putbits(fd_ou, 1);
1097                putbits(fd_ex, 2);
1098#undef putbits
1099        }
1100        if (selbits != &s_selbits[0])
1101                free(selbits, M_SELECT);
1102
1103        return (error);
1104}
1105#ifdef __rtems__
1106int
1107select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds,
1108    struct timeval *timeout)
1109{
1110        struct thread *td = rtems_bsd_get_curthread_or_null();
1111        int error;
1112
1113        if (td != NULL) {
1114                error = kern_select(td, nfds, readfds, writefds, errorfds,
1115                    timeout, NFDBITS);
1116        } else {
1117                error = ENOMEM;
1118        }
1119
1120        if (error == 0) {
1121                return td->td_retval[0];
1122        } else {
1123                rtems_set_errno_and_return_minus_one(error);
1124        }
1125}
1126#endif /* __rtems__ */
1127
1128/*
1129 * Convert a select bit set to poll flags.
1130 *
1131 * The backend always returns POLLHUP/POLLERR if appropriate and we
1132 * return this as a set bit in any set.
1133 */
1134static int select_flags[3] = {
1135    POLLRDNORM | POLLHUP | POLLERR,
1136    POLLWRNORM | POLLHUP | POLLERR,
1137    POLLRDBAND | POLLERR
1138};
1139
1140/*
1141 * Compute the fo_poll flags required for a fd given by the index and
1142 * bit position in the fd_mask array.
1143 */
1144static __inline int
1145selflags(fd_mask **ibits, int idx, fd_mask bit)
1146{
1147        int flags;
1148        int msk;
1149
1150        flags = 0;
1151        for (msk = 0; msk < 3; msk++) {
1152                if (ibits[msk] == NULL)
1153                        continue;
1154                if ((ibits[msk][idx] & bit) == 0)
1155                        continue;
1156                flags |= select_flags[msk];
1157        }
1158        return (flags);
1159}
1160
1161/*
1162 * Set the appropriate output bits given a mask of fired events and the
1163 * input bits originally requested.
1164 */
1165static __inline int
1166selsetbits(fd_mask **ibits, fd_mask **obits, int idx, fd_mask bit, int events)
1167{
1168        int msk;
1169        int n;
1170
1171        n = 0;
1172        for (msk = 0; msk < 3; msk++) {
1173                if ((events & select_flags[msk]) == 0)
1174                        continue;
1175                if (ibits[msk] == NULL)
1176                        continue;
1177                if ((ibits[msk][idx] & bit) == 0)
1178                        continue;
1179                /*
1180                 * XXX Check for a duplicate set.  This can occur because a
1181                 * socket calls selrecord() twice for each poll() call
1182                 * resulting in two selfds per real fd.  selrescan() will
1183                 * call selsetbits twice as a result.
1184                 */
1185                if ((obits[msk][idx] & bit) != 0)
1186                        continue;
1187                obits[msk][idx] |= bit;
1188                n++;
1189        }
1190
1191        return (n);
1192}
1193
1194static __inline int
1195getselfd_cap(struct filedesc *fdp, int fd, struct file **fpp)
1196{
1197        struct file *fp;
1198#ifdef CAPABILITIES
1199        struct file *fp_fromcap;
1200        int error;
1201#endif
1202
1203        if ((fp = fget_unlocked(fdp, fd)) == NULL)
1204                return (EBADF);
1205#ifdef CAPABILITIES
1206        /*
1207         * If the file descriptor is for a capability, test rights and use
1208         * the file descriptor references by the capability.
1209         */
1210        error = cap_funwrap(fp, CAP_POLL_EVENT, &fp_fromcap);
1211        if (error) {
1212                fdrop(fp, curthread);
1213                return (error);
1214        }
1215        if (fp != fp_fromcap) {
1216                fhold(fp_fromcap);
1217                fdrop(fp, curthread);
1218                fp = fp_fromcap;
1219        }
1220#endif /* CAPABILITIES */
1221        *fpp = fp;
1222        return (0);
1223}
1224
1225/*
1226 * Traverse the list of fds attached to this thread's seltd and check for
1227 * completion.
1228 */
1229static int
1230selrescan(struct thread *td, fd_mask **ibits, fd_mask **obits)
1231{
1232        struct filedesc *fdp;
1233        struct selinfo *si;
1234        struct seltd *stp;
1235        struct selfd *sfp;
1236        struct selfd *sfn;
1237        struct file *fp;
1238        fd_mask bit;
1239        int fd, ev, n, idx;
1240        int error;
1241
1242#ifndef __rtems__
1243        fdp = td->td_proc->p_fd;
1244#else /* __rtems__ */
1245        fdp = NULL;
1246#endif /* __rtems__ */
1247        stp = td->td_sel;
1248        n = 0;
1249        STAILQ_FOREACH_SAFE(sfp, &stp->st_selq, sf_link, sfn) {
1250                fd = (int)(uintptr_t)sfp->sf_cookie;
1251                si = sfp->sf_si;
1252                selfdfree(stp, sfp);
1253                /* If the selinfo wasn't cleared the event didn't fire. */
1254                if (si != NULL)
1255                        continue;
1256                error = getselfd_cap(fdp, fd, &fp);
1257                if (error)
1258                        return (error);
1259                idx = fd / NFDBITS;
1260                bit = (fd_mask)1 << (fd % NFDBITS);
1261                ev = fo_poll(fp, selflags(ibits, idx, bit), td->td_ucred, td);
1262                fdrop(fp, td);
1263                if (ev != 0)
1264                        n += selsetbits(ibits, obits, idx, bit, ev);
1265        }
1266        stp->st_flags = 0;
1267        td->td_retval[0] = n;
1268        return (0);
1269}
1270
1271/*
1272 * Perform the initial filedescriptor scan and register ourselves with
1273 * each selinfo.
1274 */
1275static int
1276selscan(td, ibits, obits, nfd)
1277        struct thread *td;
1278        fd_mask **ibits, **obits;
1279        int nfd;
1280{
1281        struct filedesc *fdp;
1282        struct file *fp;
1283        fd_mask bit;
1284        int ev, flags, end, fd;
1285        int n, idx;
1286        int error;
1287
1288#ifndef __rtems__
1289        fdp = td->td_proc->p_fd;
1290#else /* __rtems__ */
1291        fdp = NULL;
1292#endif /* __rtems__ */
1293        n = 0;
1294        for (idx = 0, fd = 0; fd < nfd; idx++) {
1295                end = imin(fd + NFDBITS, nfd);
1296                for (bit = 1; fd < end; bit <<= 1, fd++) {
1297                        /* Compute the list of events we're interested in. */
1298                        flags = selflags(ibits, idx, bit);
1299                        if (flags == 0)
1300                                continue;
1301                        error = getselfd_cap(fdp, fd, &fp);
1302                        if (error)
1303                                return (error);
1304                        selfdalloc(td, (void *)(uintptr_t)fd);
1305                        ev = fo_poll(fp, flags, td->td_ucred, td);
1306                        fdrop(fp, td);
1307                        if (ev != 0)
1308                                n += selsetbits(ibits, obits, idx, bit, ev);
1309                }
1310        }
1311
1312        td->td_retval[0] = n;
1313        return (0);
1314}
1315
1316#ifndef _SYS_SYSPROTO_H_
1317struct poll_args {
1318        struct pollfd *fds;
1319        u_int   nfds;
1320        int     timeout;
1321};
1322#endif
1323#ifdef __rtems__
1324static
1325#endif /* __rtems__ */
1326int
1327sys_poll(td, uap)
1328        struct thread *td;
1329        struct poll_args *uap;
1330{
1331        struct pollfd *bits;
1332        struct pollfd smallbits[32];
1333        struct timeval atv, rtv, ttv;
1334        int error, timo;
1335        u_int nfds;
1336        size_t ni;
1337
1338        nfds = uap->nfds;
1339#ifndef __rtems__
1340        if (nfds > maxfilesperproc && nfds > FD_SETSIZE)
1341#else /* __rtems__ */
1342        if (nfds > rtems_libio_number_iops)
1343#endif /* __rtems__ */
1344                return (EINVAL);
1345        ni = nfds * sizeof(struct pollfd);
1346        if (ni > sizeof(smallbits))
1347                bits = malloc(ni, M_TEMP, M_WAITOK);
1348        else
1349                bits = smallbits;
1350        error = copyin(uap->fds, bits, ni);
1351        if (error)
1352                goto done;
1353        if (uap->timeout != INFTIM) {
1354                atv.tv_sec = uap->timeout / 1000;
1355                atv.tv_usec = (uap->timeout % 1000) * 1000;
1356                if (itimerfix(&atv)) {
1357                        error = EINVAL;
1358                        goto done;
1359                }
1360                getmicrouptime(&rtv);
1361                timevaladd(&atv, &rtv);
1362        } else {
1363                atv.tv_sec = 0;
1364                atv.tv_usec = 0;
1365        }
1366        timo = 0;
1367        seltdinit(td);
1368        /* Iterate until the timeout expires or descriptors become ready. */
1369        for (;;) {
1370                error = pollscan(td, bits, nfds);
1371                if (error || td->td_retval[0] != 0)
1372                        break;
1373                if (atv.tv_sec || atv.tv_usec) {
1374                        getmicrouptime(&rtv);
1375                        if (timevalcmp(&rtv, &atv, >=))
1376                                break;
1377                        ttv = atv;
1378                        timevalsub(&ttv, &rtv);
1379                        timo = ttv.tv_sec > 24 * 60 * 60 ?
1380                            24 * 60 * 60 * hz : tvtohz(&ttv);
1381                }
1382                error = seltdwait(td, timo);
1383                if (error)
1384                        break;
1385                error = pollrescan(td);
1386                if (error || td->td_retval[0] != 0)
1387                        break;
1388        }
1389        seltdclear(td);
1390
1391done:
1392        /* poll is not restarted after signals... */
1393        if (error == ERESTART)
1394                error = EINTR;
1395        if (error == EWOULDBLOCK)
1396                error = 0;
1397        if (error == 0) {
1398                error = pollout(td, bits, uap->fds, nfds);
1399                if (error)
1400                        goto out;
1401        }
1402out:
1403        if (ni > sizeof(smallbits))
1404                free(bits, M_TEMP);
1405        return (error);
1406}
1407#ifdef __rtems__
1408int
1409poll(struct pollfd fds[], nfds_t nfds, int timeout)
1410{
1411        struct thread *td = rtems_bsd_get_curthread_or_null();
1412        struct poll_args ua = {
1413                .fds = &fds[0],
1414                .nfds = nfds,
1415                .timeout = timeout
1416        };
1417        int error;
1418
1419        if (td != NULL) {
1420                error = sys_poll(td, &ua);
1421        } else {
1422                error = ENOMEM;
1423        }
1424
1425        if (error == 0) {
1426                return td->td_retval[0];
1427        } else {
1428                rtems_set_errno_and_return_minus_one(error);
1429        }
1430}
1431#endif /* __rtems__ */
1432
1433static int
1434pollrescan(struct thread *td)
1435{
1436        struct seltd *stp;
1437        struct selfd *sfp;
1438        struct selfd *sfn;
1439        struct selinfo *si;
1440        struct filedesc *fdp;
1441        struct file *fp;
1442        struct pollfd *fd;
1443        int n;
1444
1445        n = 0;
1446#ifndef __rtems__
1447        fdp = td->td_proc->p_fd;
1448#else /* __rtems__ */
1449        fdp = NULL;
1450#endif /* __rtems__ */
1451        stp = td->td_sel;
1452        FILEDESC_SLOCK(fdp);
1453        STAILQ_FOREACH_SAFE(sfp, &stp->st_selq, sf_link, sfn) {
1454                fd = (struct pollfd *)sfp->sf_cookie;
1455                si = sfp->sf_si;
1456                selfdfree(stp, sfp);
1457                /* If the selinfo wasn't cleared the event didn't fire. */
1458                if (si != NULL)
1459                        continue;
1460#ifndef __rtems__
1461                fp = fdp->fd_ofiles[fd->fd];
1462#else /* __rtems__ */
1463                fp = fget_unlocked(fdp, fd->fd);
1464#endif /* __rtems__ */
1465#ifdef CAPABILITIES
1466                if ((fp == NULL)
1467                    || (cap_funwrap(fp, CAP_POLL_EVENT, &fp) != 0)) {
1468#else
1469                if (fp == NULL) {
1470#endif
1471                        fd->revents = POLLNVAL;
1472                        n++;
1473                        continue;
1474                }
1475
1476                /*
1477                 * Note: backend also returns POLLHUP and
1478                 * POLLERR if appropriate.
1479                 */
1480                fd->revents = fo_poll(fp, fd->events, td->td_ucred, td);
1481                if (fd->revents != 0)
1482                        n++;
1483        }
1484        FILEDESC_SUNLOCK(fdp);
1485        stp->st_flags = 0;
1486        td->td_retval[0] = n;
1487        return (0);
1488}
1489
1490
1491static int
1492pollout(td, fds, ufds, nfd)
1493        struct thread *td;
1494        struct pollfd *fds;
1495        struct pollfd *ufds;
1496        u_int nfd;
1497{
1498        int error = 0;
1499        u_int i = 0;
1500        u_int n = 0;
1501
1502        for (i = 0; i < nfd; i++) {
1503                error = copyout(&fds->revents, &ufds->revents,
1504                    sizeof(ufds->revents));
1505                if (error)
1506                        return (error);
1507                if (fds->revents != 0)
1508                        n++;
1509                fds++;
1510                ufds++;
1511        }
1512        td->td_retval[0] = n;
1513        return (0);
1514}
1515
1516static int
1517pollscan(td, fds, nfd)
1518        struct thread *td;
1519        struct pollfd *fds;
1520        u_int nfd;
1521{
1522#ifndef __rtems__
1523        struct filedesc *fdp = td->td_proc->p_fd;
1524#else /* __rtems__ */
1525        struct filedesc *fdp = NULL;
1526#endif /* __rtems__ */
1527        int i;
1528        struct file *fp;
1529        int n = 0;
1530
1531        FILEDESC_SLOCK(fdp);
1532        for (i = 0; i < nfd; i++, fds++) {
1533#ifndef __rtems__
1534                if (fds->fd >= fdp->fd_nfiles) {
1535#else /* __rtems__ */
1536                if (fds->fd >= rtems_libio_number_iops) {
1537#endif /* __rtems__ */
1538                        fds->revents = POLLNVAL;
1539                        n++;
1540                } else if (fds->fd < 0) {
1541                        fds->revents = 0;
1542                } else {
1543#ifndef __rtems__
1544                        fp = fdp->fd_ofiles[fds->fd];
1545#else /* __rtems__ */
1546                        fp = fget_unlocked(fdp, fds->fd);
1547#endif /* __rtems__ */
1548#ifdef CAPABILITIES
1549                        if ((fp == NULL)
1550                            || (cap_funwrap(fp, CAP_POLL_EVENT, &fp) != 0)) {
1551#else
1552                        if (fp == NULL) {
1553#endif
1554                                fds->revents = POLLNVAL;
1555                                n++;
1556                        } else {
1557                                /*
1558                                 * Note: backend also returns POLLHUP and
1559                                 * POLLERR if appropriate.
1560                                 */
1561                                selfdalloc(td, fds);
1562                                fds->revents = fo_poll(fp, fds->events,
1563                                    td->td_ucred, td);
1564                                /*
1565                                 * POSIX requires POLLOUT to be never
1566                                 * set simultaneously with POLLHUP.
1567                                 */
1568                                if ((fds->revents & POLLHUP) != 0)
1569                                        fds->revents &= ~POLLOUT;
1570
1571                                if (fds->revents != 0)
1572                                        n++;
1573                        }
1574                }
1575        }
1576        FILEDESC_SUNLOCK(fdp);
1577        td->td_retval[0] = n;
1578        return (0);
1579}
1580
1581#ifndef __rtems__
1582/*
1583 * OpenBSD poll system call.
1584 *
1585 * XXX this isn't quite a true representation..  OpenBSD uses select ops.
1586 */
1587#ifndef _SYS_SYSPROTO_H_
1588struct openbsd_poll_args {
1589        struct pollfd *fds;
1590        u_int   nfds;
1591        int     timeout;
1592};
1593#endif
1594int
1595sys_openbsd_poll(td, uap)
1596        register struct thread *td;
1597        register struct openbsd_poll_args *uap;
1598{
1599        return (sys_poll(td, (struct poll_args *)uap));
1600}
1601
1602/*
1603 * XXX This was created specifically to support netncp and netsmb.  This
1604 * allows the caller to specify a socket to wait for events on.  It returns
1605 * 0 if any events matched and an error otherwise.  There is no way to
1606 * determine which events fired.
1607 */
1608int
1609selsocket(struct socket *so, int events, struct timeval *tvp, struct thread *td)
1610{
1611        struct timeval atv, rtv, ttv;
1612        int error, timo;
1613
1614        if (tvp != NULL) {
1615                atv = *tvp;
1616                if (itimerfix(&atv))
1617                        return (EINVAL);
1618                getmicrouptime(&rtv);
1619                timevaladd(&atv, &rtv);
1620        } else {
1621                atv.tv_sec = 0;
1622                atv.tv_usec = 0;
1623        }
1624
1625        timo = 0;
1626        seltdinit(td);
1627        /*
1628         * Iterate until the timeout expires or the socket becomes ready.
1629         */
1630        for (;;) {
1631                selfdalloc(td, NULL);
1632                error = sopoll(so, events, NULL, td);
1633                /* error here is actually the ready events. */
1634                if (error)
1635                        return (0);
1636                if (atv.tv_sec || atv.tv_usec) {
1637                        getmicrouptime(&rtv);
1638                        if (timevalcmp(&rtv, &atv, >=)) {
1639                                seltdclear(td);
1640                                return (EWOULDBLOCK);
1641                        }
1642                        ttv = atv;
1643                        timevalsub(&ttv, &rtv);
1644                        timo = ttv.tv_sec > 24 * 60 * 60 ?
1645                            24 * 60 * 60 * hz : tvtohz(&ttv);
1646                }
1647                error = seltdwait(td, timo);
1648                seltdclear(td);
1649                if (error)
1650                        break;
1651        }
1652        /* XXX Duplicates ncp/smb behavior. */
1653        if (error == ERESTART)
1654                error = 0;
1655        return (error);
1656}
1657#endif /* __rtems__ */
1658
1659/*
1660 * Preallocate two selfds associated with 'cookie'.  Some fo_poll routines
1661 * have two select sets, one for read and another for write.
1662 */
1663static void
1664selfdalloc(struct thread *td, void *cookie)
1665{
1666        struct seltd *stp;
1667
1668        stp = td->td_sel;
1669        if (stp->st_free1 == NULL)
1670                stp->st_free1 = uma_zalloc(selfd_zone, M_WAITOK|M_ZERO);
1671        stp->st_free1->sf_td = stp;
1672        stp->st_free1->sf_cookie = cookie;
1673        if (stp->st_free2 == NULL)
1674                stp->st_free2 = uma_zalloc(selfd_zone, M_WAITOK|M_ZERO);
1675        stp->st_free2->sf_td = stp;
1676        stp->st_free2->sf_cookie = cookie;
1677}
1678
1679static void
1680selfdfree(struct seltd *stp, struct selfd *sfp)
1681{
1682        STAILQ_REMOVE(&stp->st_selq, sfp, selfd, sf_link);
1683        mtx_lock(sfp->sf_mtx);
1684        if (sfp->sf_si)
1685                TAILQ_REMOVE(&sfp->sf_si->si_tdlist, sfp, sf_threads);
1686        mtx_unlock(sfp->sf_mtx);
1687        uma_zfree(selfd_zone, sfp);
1688}
1689
1690/* Drain the waiters tied to all the selfd belonging the specified selinfo. */
1691void
1692seldrain(sip)
1693        struct selinfo *sip;
1694{
1695
1696        /*
1697         * This feature is already provided by doselwakeup(), thus it is
1698         * enough to go for it.
1699         * Eventually, the context, should take care to avoid races
1700         * between thread calling select()/poll() and file descriptor
1701         * detaching, but, again, the races are just the same as
1702         * selwakeup().
1703         */
1704        doselwakeup(sip, -1);
1705}
1706
1707/*
1708 * Record a select request.
1709 */
1710void
1711selrecord(selector, sip)
1712        struct thread *selector;
1713        struct selinfo *sip;
1714{
1715        struct selfd *sfp;
1716        struct seltd *stp;
1717        struct mtx *mtxp;
1718
1719        stp = selector->td_sel;
1720        /*
1721         * Don't record when doing a rescan.
1722         */
1723        if (stp->st_flags & SELTD_RESCAN)
1724                return;
1725        /*
1726         * Grab one of the preallocated descriptors.
1727         */
1728        sfp = NULL;
1729        if ((sfp = stp->st_free1) != NULL)
1730                stp->st_free1 = NULL;
1731        else if ((sfp = stp->st_free2) != NULL)
1732                stp->st_free2 = NULL;
1733        else
1734                panic("selrecord: No free selfd on selq");
1735        mtxp = sip->si_mtx;
1736        if (mtxp == NULL)
1737                mtxp = mtx_pool_find(mtxpool_select, sip);
1738        /*
1739         * Initialize the sfp and queue it in the thread.
1740         */
1741        sfp->sf_si = sip;
1742        sfp->sf_mtx = mtxp;
1743        STAILQ_INSERT_TAIL(&stp->st_selq, sfp, sf_link);
1744        /*
1745         * Now that we've locked the sip, check for initialization.
1746         */
1747        mtx_lock(mtxp);
1748        if (sip->si_mtx == NULL) {
1749                sip->si_mtx = mtxp;
1750                TAILQ_INIT(&sip->si_tdlist);
1751        }
1752        /*
1753         * Add this thread to the list of selfds listening on this selinfo.
1754         */
1755        TAILQ_INSERT_TAIL(&sip->si_tdlist, sfp, sf_threads);
1756        mtx_unlock(sip->si_mtx);
1757}
1758
1759/* Wake up a selecting thread. */
1760void
1761selwakeup(sip)
1762        struct selinfo *sip;
1763{
1764        doselwakeup(sip, -1);
1765}
1766
1767/* Wake up a selecting thread, and set its priority. */
1768void
1769selwakeuppri(sip, pri)
1770        struct selinfo *sip;
1771        int pri;
1772{
1773        doselwakeup(sip, pri);
1774}
1775
1776/*
1777 * Do a wakeup when a selectable event occurs.
1778 */
1779static void
1780doselwakeup(sip, pri)
1781        struct selinfo *sip;
1782        int pri;
1783{
1784        struct selfd *sfp;
1785        struct selfd *sfn;
1786        struct seltd *stp;
1787
1788        /* If it's not initialized there can't be any waiters. */
1789        if (sip->si_mtx == NULL)
1790                return;
1791        /*
1792         * Locking the selinfo locks all selfds associated with it.
1793         */
1794        mtx_lock(sip->si_mtx);
1795        TAILQ_FOREACH_SAFE(sfp, &sip->si_tdlist, sf_threads, sfn) {
1796                /*
1797                 * Once we remove this sfp from the list and clear the
1798                 * sf_si seltdclear will know to ignore this si.
1799                 */
1800                TAILQ_REMOVE(&sip->si_tdlist, sfp, sf_threads);
1801                sfp->sf_si = NULL;
1802                stp = sfp->sf_td;
1803                mtx_lock(&stp->st_mtx);
1804                stp->st_flags |= SELTD_PENDING;
1805                cv_broadcastpri(&stp->st_wait, pri);
1806                mtx_unlock(&stp->st_mtx);
1807        }
1808        mtx_unlock(sip->si_mtx);
1809}
1810
1811static void
1812seltdinit(struct thread *td)
1813{
1814        struct seltd *stp;
1815
1816        if ((stp = td->td_sel) != NULL)
1817                goto out;
1818        td->td_sel = stp = malloc(sizeof(*stp), M_SELECT, M_WAITOK|M_ZERO);
1819        mtx_init(&stp->st_mtx, "sellck", NULL, MTX_DEF);
1820        cv_init(&stp->st_wait, "select");
1821out:
1822        stp->st_flags = 0;
1823        STAILQ_INIT(&stp->st_selq);
1824}
1825
1826static int
1827seltdwait(struct thread *td, int timo)
1828{
1829        struct seltd *stp;
1830        int error;
1831
1832        stp = td->td_sel;
1833        /*
1834         * An event of interest may occur while we do not hold the seltd
1835         * locked so check the pending flag before we sleep.
1836         */
1837        mtx_lock(&stp->st_mtx);
1838        /*
1839         * Any further calls to selrecord will be a rescan.
1840         */
1841        stp->st_flags |= SELTD_RESCAN;
1842        if (stp->st_flags & SELTD_PENDING) {
1843                mtx_unlock(&stp->st_mtx);
1844                return (0);
1845        }
1846        if (timo > 0)
1847                error = cv_timedwait_sig(&stp->st_wait, &stp->st_mtx, timo);
1848        else
1849                error = cv_wait_sig(&stp->st_wait, &stp->st_mtx);
1850        mtx_unlock(&stp->st_mtx);
1851
1852        return (error);
1853}
1854
1855void
1856seltdfini(struct thread *td)
1857{
1858        struct seltd *stp;
1859
1860        stp = td->td_sel;
1861        if (stp == NULL)
1862                return;
1863        if (stp->st_free1)
1864                uma_zfree(selfd_zone, stp->st_free1);
1865        if (stp->st_free2)
1866                uma_zfree(selfd_zone, stp->st_free2);
1867        td->td_sel = NULL;
1868        free(stp, M_SELECT);
1869}
1870
1871/*
1872 * Remove the references to the thread from all of the objects we were
1873 * polling.
1874 */
1875static void
1876seltdclear(struct thread *td)
1877{
1878        struct seltd *stp;
1879        struct selfd *sfp;
1880        struct selfd *sfn;
1881
1882        stp = td->td_sel;
1883        STAILQ_FOREACH_SAFE(sfp, &stp->st_selq, sf_link, sfn)
1884                selfdfree(stp, sfp);
1885        stp->st_flags = 0;
1886}
1887
1888static void selectinit(void *);
1889SYSINIT(select, SI_SUB_SYSCALLS, SI_ORDER_ANY, selectinit, NULL);
1890static void
1891selectinit(void *dummy __unused)
1892{
1893
1894        selfd_zone = uma_zcreate("selfd", sizeof(struct selfd), NULL, NULL,
1895            NULL, NULL, UMA_ALIGN_PTR, 0);
1896        mtxpool_select = mtx_pool_create("select mtxpool", 128, MTX_DEF);
1897}
1898#ifdef __rtems__
1899#include <machine/rtems-bsd-thread.h>
1900
1901#include <rtems/score/objectimpl.h>
1902#include <rtems/score/threadimpl.h>
1903
1904#include <rtems/bsd/util.h>
1905
1906static void
1907force_select_timeout(Thread_Control *thread)
1908{
1909        struct thread *td = rtems_bsd_get_thread(thread);
1910
1911        if (td != NULL) {
1912                struct seltd *stp = td->td_sel;
1913
1914                cv_broadcastpri(&stp->st_wait, 0);
1915        }
1916}
1917
1918rtems_status_code rtems_bsd_force_select_timeout(rtems_id task_id)
1919{
1920        Thread_Control *thread;
1921        Objects_Locations location;
1922
1923        thread = _Thread_Get(task_id, &location);
1924        switch (location) {
1925                case OBJECTS_LOCAL:
1926                        force_select_timeout(thread);
1927                        _Objects_Put(&thread->Object);
1928                        break;
1929#if defined(RTEMS_MULTIPROCESSING)
1930                case OBJECTS_REMOTE:
1931                        _Thread_Dispatch();
1932                        return (RTEMS_ILLEGAL_ON_REMOTE_OBJECT);
1933#endif
1934                default:
1935                        return (RTEMS_INVALID_ID);
1936        }
1937
1938        return (RTEMS_SUCCESSFUL);
1939}
1940#endif /* __rtems__ */
Note: See TracBrowser for help on using the repository browser.