Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Add the code for pselect and pollts. Add selcommon and ...



details:   https://anonhg.NetBSD.org/src/rev/14509eee2cec
branches:  trunk
changeset: 574255:14509eee2cec
user:      matt <matt%NetBSD.org@localhost>
date:      Fri Feb 25 19:56:07 2005 +0000

description:
Add the code for pselect and pollts.  Add selcommon and pollcommon to
<sys/select.h> and <sys/poll.h>.

diffstat:

 sys/kern/sys_generic.c |  191 ++++++++++++++++++++++++++++++++++++++----------
 sys/sys/poll.h         |   11 ++-
 sys/sys/select.h       |    8 +-
 3 files changed, 165 insertions(+), 45 deletions(-)

diffs (truncated from 381 to 300 lines):

diff -r 2472c2f3799e -r 14509eee2cec sys/kern/sys_generic.c
--- a/sys/kern/sys_generic.c    Fri Feb 25 19:55:18 2005 +0000
+++ b/sys/kern/sys_generic.c    Fri Feb 25 19:56:07 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sys_generic.c,v 1.81 2004/03/23 13:22:04 junyoung Exp $        */
+/*     $NetBSD: sys_generic.c,v 1.82 2005/02/25 19:56:07 matt Exp $    */
 
 /*
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_generic.c,v 1.81 2004/03/23 13:22:04 junyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_generic.c,v 1.82 2005/02/25 19:56:07 matt Exp $");
 
 #include "opt_ktrace.h"
 
@@ -65,6 +65,7 @@
 int selscan(struct proc *, fd_mask *, fd_mask *, int, register_t *);
 int pollscan(struct proc *, struct pollfd *, int, register_t *);
 
+
 /*
  * Read system call.
  */
@@ -654,6 +655,41 @@
  * Select system call.
  */
 int
+sys_pselect(struct lwp *l, void *v, register_t *retval)
+{
+       struct sys_pselect_args /* {
+               syscallarg(int)                         nd;
+               syscallarg(fd_set *)                    in;
+               syscallarg(fd_set *)                    ou;
+               syscallarg(fd_set *)                    ex;
+               syscallarg(const struct timespec *)     ts;
+               syscallarg(sigset_t *)                  mask;
+       } */ * const uap = v;
+       struct timespec ats;
+       struct timeval  atv, *tv = NULL;
+       sigset_t        amask, *mask = NULL;
+       int             error;
+
+       if (SCARG(uap, ts)) {
+               error = copyin(SCARG(uap, ts), &ats, sizeof(ats));
+               if (error)
+                       return error;
+               atv.tv_sec = ats.tv_sec;
+               atv.tv_usec = ats.tv_nsec / 1000;
+               tv = &atv;
+       }
+       if (SCARG(uap, mask) != NULL) {
+               error = copyin(SCARG(uap, mask), &amask, sizeof(amask));
+               if (error)
+                       return error;
+               mask = &amask;
+       }
+
+       return selcommon(l, retval, SCARG(uap, nd), SCARG(uap, in),
+           SCARG(uap, ou), SCARG(uap, ex), tv, mask);
+}
+
+int
 sys_select(struct lwp *l, void *v, register_t *retval)
 {
        struct sys_select_args /* {
@@ -662,32 +698,50 @@
                syscallarg(fd_set *)            ou;
                syscallarg(fd_set *)            ex;
                syscallarg(struct timeval *)    tv;
-       } */ *uap = v;
-       struct proc     *p;
+       } */ * const uap = v;
+       struct timeval atv, *tv = NULL;
+       int error;
+
+       if (SCARG(uap, tv)) {
+               error = copyin(SCARG(uap, tv), (caddr_t)&atv,
+                       sizeof(atv));
+               if (error)
+                       return error;
+               tv = &atv;
+       }
+
+       return selcommon(l, retval, SCARG(uap, nd), SCARG(uap, in),
+           SCARG(uap, ou), SCARG(uap, ex), tv, NULL);
+}
+
+int
+selcommon(struct lwp *l, register_t *retval, int nd, fd_set *u_in,
+       fd_set *u_ou, fd_set *u_ex, struct timeval *tv, sigset_t *mask)
+{
+       struct proc     * const p = l->l_proc;
        caddr_t         bits;
        char            smallbits[howmany(FD_SETSIZE, NFDBITS) *
                            sizeof(fd_mask) * 6];
-       struct          timeval atv;
        int             s, ncoll, error, timo;
        size_t          ni;
+       sigset_t        oldmask;
 
        error = 0;
-       p = l->l_proc;
-       if (SCARG(uap, nd) < 0)
+       if (nd < 0)
                return (EINVAL);
-       if (SCARG(uap, nd) > p->p_fd->fd_nfiles) {
+       if (nd > p->p_fd->fd_nfiles) {
                /* forgiving; slightly wrong */
-               SCARG(uap, nd) = p->p_fd->fd_nfiles;
+               nd = p->p_fd->fd_nfiles;
        }
-       ni = howmany(SCARG(uap, nd), NFDBITS) * sizeof(fd_mask);
+       ni = howmany(nd, NFDBITS) * sizeof(fd_mask);
        if (ni * 6 > sizeof(smallbits))
                bits = malloc(ni * 6, M_TEMP, M_WAITOK);
        else
                bits = smallbits;
 
 #define        getbits(name, x)                                                \
-       if (SCARG(uap, name)) {                                         \
-               error = copyin(SCARG(uap, name), bits + ni * x, ni);    \
+       if (u_ ## name) {                                               \
+               error = copyin(u_ ## name, bits + ni * x, ni);          \
                if (error)                                              \
                        goto done;                                      \
        } else                                                          \
@@ -698,32 +752,30 @@
 #undef getbits
 
        timo = 0;
-       if (SCARG(uap, tv)) {
-               error = copyin(SCARG(uap, tv), (caddr_t)&atv,
-                       sizeof(atv));
-               if (error)
-                       goto done;
-               if (itimerfix(&atv)) {
+       if (tv) {
+               if (itimerfix(tv)) {
                        error = EINVAL;
                        goto done;
                }
                s = splclock();
-               timeradd(&atv, &time, &atv);
+               timeradd(tv, &time, tv);
                splx(s);
        }
+       if (mask)
+               (void)sigprocmask1(p, SIG_SETMASK, mask, &oldmask);
 
  retry:
        ncoll = nselcoll;
        l->l_flag |= L_SELECT;
        error = selscan(p, (fd_mask *)(bits + ni * 0),
-                          (fd_mask *)(bits + ni * 3), SCARG(uap, nd), retval);
+                          (fd_mask *)(bits + ni * 3), nd, retval);
        if (error || *retval)
                goto done;
-       if (SCARG(uap, tv)) {
+       if (tv) {
                /*
                 * We have to recalculate the timeout on every retry.
                 */
-               timo = hzto(&atv);
+               timo = hzto(tv);
                if (timo <= 0)
                        goto done;
        }
@@ -738,6 +790,8 @@
        if (error == 0)
                goto retry;
  done:
+       if (mask)
+               (void)sigprocmask1(p, SIG_SETMASK, &oldmask, NULL);
        l->l_flag &= ~L_SELECT;
        /* select is not restarted after signals... */
        if (error == ERESTART)
@@ -747,8 +801,8 @@
        if (error == 0) {
 
 #define        putbits(name, x)                                                \
-               if (SCARG(uap, name)) {                                 \
-                       error = copyout(bits + ni * x, SCARG(uap, name), ni); \
+               if (u_ ## name) {                                       \
+                       error = copyout(bits + ni * x, u_ ## name, ni); \
                        if (error)                                      \
                                goto out;                               \
                }
@@ -809,54 +863,105 @@
                syscallarg(struct pollfd *)     fds;
                syscallarg(u_int)               nfds;
                syscallarg(int)                 timeout;
-       } */ *uap = v;
-       struct proc     *p;
+       } */ * const uap = v;
+       struct timeval  atv, *tv = NULL;
+
+       if (SCARG(uap, timeout) != INFTIM) {
+               atv.tv_sec = SCARG(uap, timeout) / 1000;
+               atv.tv_usec = (SCARG(uap, timeout) % 1000) * 1000;
+               tv = &atv;
+       }
+
+       return pollcommon(l, retval, SCARG(uap, fds), SCARG(uap, nfds),
+               tv, NULL);
+}
+
+/*
+ * Poll system call.
+ */
+int
+sys_pollts(struct lwp *l, void *v, register_t *retval)
+{
+       struct sys_pollts_args /* {
+               syscallarg(struct pollfd *)             fds;
+               syscallarg(u_int)                       nfds;
+               syscallarg(const struct timespec *)     ts;
+               syscallarg(const sigset_t *)            mask;
+       } */ * const uap = v;
+       struct timespec ats;
+       struct timeval  atv, *tv = NULL;
+       sigset_t        amask, *mask = NULL;
+       int             error;
+
+       if (SCARG(uap, ts)) {
+               error = copyin(SCARG(uap, ts), &ats, sizeof(ats));
+               if (error)
+                       return error;
+               atv.tv_sec = ats.tv_sec;
+               atv.tv_usec = ats.tv_nsec / 1000;
+               tv = &atv;
+       }
+       if (SCARG(uap, mask)) {
+               error = copyin(SCARG(uap, mask), &amask, sizeof(amask));
+               if (error)
+                       return error;
+               mask = &amask;
+       }
+
+       return pollcommon(l, retval, SCARG(uap, fds), SCARG(uap, nfds),
+               tv, mask);
+}
+
+int
+pollcommon(struct lwp *l, register_t *retval,
+       struct pollfd *u_fds, u_int nfds,
+       struct timeval *tv, sigset_t *mask)
+{
+       struct proc     * const p = l->l_proc;
        caddr_t         bits;
        char            smallbits[32 * sizeof(struct pollfd)];
-       struct timeval  atv;
+       sigset_t        oldmask;
        int             s, ncoll, error, timo;
        size_t          ni;
 
-       error = 0;
-       p = l->l_proc;
-       if (SCARG(uap, nfds) > p->p_fd->fd_nfiles) {
+       if (nfds > p->p_fd->fd_nfiles) {
                /* forgiving; slightly wrong */
-               SCARG(uap, nfds) = p->p_fd->fd_nfiles;
+               nfds = p->p_fd->fd_nfiles;
        }
-       ni = SCARG(uap, nfds) * sizeof(struct pollfd);
+       ni = nfds * sizeof(struct pollfd);
        if (ni > sizeof(smallbits))
                bits = malloc(ni, M_TEMP, M_WAITOK);
        else
                bits = smallbits;
 
-       error = copyin(SCARG(uap, fds), bits, ni);
+       error = copyin(u_fds, bits, ni);
        if (error)
                goto done;
 
        timo = 0;
-       if (SCARG(uap, timeout) != INFTIM) {
-               atv.tv_sec = SCARG(uap, timeout) / 1000;
-               atv.tv_usec = (SCARG(uap, timeout) % 1000) * 1000;
-               if (itimerfix(&atv)) {
+       if (tv) {
+               if (itimerfix(tv)) {
                        error = EINVAL;
                        goto done;
                }
                s = splclock();
-               timeradd(&atv, &time, &atv);
+               timeradd(tv, &time, tv);
                splx(s);
        }
+       if (mask != NULL)
+               (void)sigprocmask1(p, SIG_SETMASK, mask, &oldmask);
 
  retry:
        ncoll = nselcoll;
        l->l_flag |= L_SELECT;
-       error = pollscan(p, (struct pollfd *)bits, SCARG(uap, nfds), retval);



Home | Main Index | Thread Index | Old Index