OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [net/] [tcpip/] [v2_0/] [src/] [sys/] [kern/] [sys_generic.c] - Diff between revs 27 and 174

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 27 Rev 174
//==========================================================================
//==========================================================================
//
//
//      sys/kern/sys_generic.c
//      sys/kern/sys_generic.c
//
//
//     
//     
//
//
//==========================================================================
//==========================================================================
//####BSDCOPYRIGHTBEGIN####
//####BSDCOPYRIGHTBEGIN####
//
//
// -------------------------------------------
// -------------------------------------------
//
//
// Portions of this software may have been derived from OpenBSD or other sources,
// Portions of this software may have been derived from OpenBSD or other sources,
// and are covered by the appropriate copyright disclaimers included herein.
// and are covered by the appropriate copyright disclaimers included herein.
//
//
// -------------------------------------------
// -------------------------------------------
//
//
//####BSDCOPYRIGHTEND####
//####BSDCOPYRIGHTEND####
//==========================================================================
//==========================================================================
//#####DESCRIPTIONBEGIN####
//#####DESCRIPTIONBEGIN####
//
//
// Author(s):    gthomas
// Author(s):    gthomas
// Contributors: gthomas
// Contributors: gthomas
// Date:         2000-01-10
// Date:         2000-01-10
// Purpose:      
// Purpose:      
// Description:  
// Description:  
//              
//              
//
//
//####DESCRIPTIONEND####
//####DESCRIPTIONEND####
//
//
//==========================================================================
//==========================================================================
 
 
 
 
/*      $OpenBSD: sys_generic.c,v 1.22 1999/11/29 22:02:14 deraadt Exp $        */
/*      $OpenBSD: sys_generic.c,v 1.22 1999/11/29 22:02:14 deraadt Exp $        */
/*      $NetBSD: sys_generic.c,v 1.24 1996/03/29 00:25:32 cgd Exp $     */
/*      $NetBSD: sys_generic.c,v 1.24 1996/03/29 00:25:32 cgd Exp $     */
 
 
/*
/*
 * Copyright (c) 1996 Theo de Raadt
 * Copyright (c) 1996 Theo de Raadt
 * Copyright (c) 1982, 1986, 1989, 1993
 * Copyright (c) 1982, 1986, 1989, 1993
 *      The Regents of the University of California.  All rights reserved.
 *      The Regents of the University of California.  All rights reserved.
 * (c) UNIX System Laboratories, Inc.
 * (c) UNIX System Laboratories, Inc.
 * All or some portions of this file are derived from material licensed
 * All or some portions of this file are derived from material licensed
 * to the University of California by American Telephone and Telegraph
 * to the University of California by American Telephone and Telegraph
 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
 * the permission of UNIX System Laboratories, Inc.
 * the permission of UNIX System Laboratories, Inc.
 *
 *
 * Redistribution and use in source and binary forms, with or without
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * modification, are permitted provided that the following conditions
 * are met:
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    must display the following acknowledgement:
 *      This product includes software developed by the University of
 *      This product includes software developed by the University of
 *      California, Berkeley and its contributors.
 *      California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *    without specific prior written permission.
 *
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * SUCH DAMAGE.
 *
 *
 *      @(#)sys_generic.c       8.5 (Berkeley) 1/21/94
 *      @(#)sys_generic.c       8.5 (Berkeley) 1/21/94
 */
 */
 
 
#include <sys/param.h>
#include <sys/param.h>
#ifndef __ECOS
#ifndef __ECOS
#include <sys/systm.h>
#include <sys/systm.h>
#include <sys/filedesc.h>
#include <sys/filedesc.h>
#endif // __ECOS
#endif // __ECOS
#include <sys/ioctl.h>
#include <sys/ioctl.h>
#ifdef __ECOS
#ifdef __ECOS
#include <cyg/io/file.h>
#include <cyg/io/file.h>
#else // __ECOS
#else // __ECOS
#include <sys/file.h>
#include <sys/file.h>
#include <sys/proc.h>
#include <sys/proc.h>
#include <sys/resourcevar.h>
#include <sys/resourcevar.h>
#endif // __ECOS
#endif // __ECOS
#include <sys/socketvar.h>
#include <sys/socketvar.h>
#ifndef __ECOS
#ifndef __ECOS
#include <sys/signalvar.h>
#include <sys/signalvar.h>
#include <sys/kernel.h>
#include <sys/kernel.h>
#include <sys/uio.h>
#include <sys/uio.h>
#include <sys/stat.h>
#include <sys/stat.h>
#endif // __ECOS
#endif // __ECOS
#include <sys/malloc.h>
#include <sys/malloc.h>
#ifndef __ECOS
#ifndef __ECOS
#include <sys/poll.h>
#include <sys/poll.h>
#endif // __ECOS
#endif // __ECOS
#ifdef KTRACE
#ifdef KTRACE
#include <sys/ktrace.h>
#include <sys/ktrace.h>
#endif
#endif
 
 
#ifndef __ECOS
#ifndef __ECOS
#include <sys/mount.h>
#include <sys/mount.h>
#endif // __ECOS
#endif // __ECOS
#include <sys/syscallargs.h>
#include <sys/syscallargs.h>
 
 
#ifndef __ECOS
#ifndef __ECOS
int selscan __P((struct proc *, fd_set *, fd_set *, int, register_t *));
int selscan __P((struct proc *, fd_set *, fd_set *, int, register_t *));
int seltrue __P((dev_t, int, struct proc *));
int seltrue __P((dev_t, int, struct proc *));
void pollscan __P((struct proc *, struct pollfd *, int, register_t *));
void pollscan __P((struct proc *, struct pollfd *, int, register_t *));
#endif // __ECOS
#endif // __ECOS
 
 
/*
/*
 * Read system call.
 * Read system call.
 */
 */
#ifdef __ECOS
#ifdef __ECOS
int
int
sys_read(struct sys_read_args *uap, register_t *retval)
sys_read(struct sys_read_args *uap, register_t *retval)
#else
#else
/* ARGSUSED */
/* ARGSUSED */
int
int
sys_read(p, v, retval)
sys_read(p, v, retval)
        struct proc *p;
        struct proc *p;
        void *v;
        void *v;
        register_t *retval;
        register_t *retval;
#endif
#endif
{
{
#ifndef __ECOS
#ifndef __ECOS
        register struct sys_read_args /* {
        register struct sys_read_args /* {
                syscallarg(int) fd;
                syscallarg(int) fd;
                syscallarg(void *) buf;
                syscallarg(void *) buf;
                syscallarg(size_t) nbyte;
                syscallarg(size_t) nbyte;
        } */ *uap = v;
        } */ *uap = v;
        register struct filedesc *fdp = p->p_fd;
        register struct filedesc *fdp = p->p_fd;
#endif
#endif
        struct file *fp;
        struct file *fp;
        struct uio auio;
        struct uio auio;
        struct iovec aiov;
        struct iovec aiov;
        long cnt, error = 0;
        long cnt, error = 0;
#ifdef KTRACE
#ifdef KTRACE
        struct iovec ktriov;
        struct iovec ktriov;
#endif
#endif
 
 
#ifdef __ECOS
#ifdef __ECOS
        if (getfp((u_int)SCARG(uap, fd), &fp) ||
        if (getfp((u_int)SCARG(uap, fd), &fp) ||
#else
#else
        if (((u_int)SCARG(uap, fd)) >= fdp->fd_nfiles ||
        if (((u_int)SCARG(uap, fd)) >= fdp->fd_nfiles ||
            (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
            (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
#endif
#endif
            (fp->f_flag & FREAD) == 0)
            (fp->f_flag & FREAD) == 0)
                return (EBADF);
                return (EBADF);
        /* Don't allow nbyte to be larger than max return val */
        /* Don't allow nbyte to be larger than max return val */
        if (SCARG(uap, nbyte) > SSIZE_MAX)
        if (SCARG(uap, nbyte) > SSIZE_MAX)
                return(EINVAL);
                return(EINVAL);
        aiov.iov_base = (caddr_t)SCARG(uap, buf);
        aiov.iov_base = (caddr_t)SCARG(uap, buf);
        aiov.iov_len = SCARG(uap, nbyte);
        aiov.iov_len = SCARG(uap, nbyte);
        auio.uio_iov = &aiov;
        auio.uio_iov = &aiov;
        auio.uio_iovcnt = 1;
        auio.uio_iovcnt = 1;
        auio.uio_resid = SCARG(uap, nbyte);
        auio.uio_resid = SCARG(uap, nbyte);
        auio.uio_rw = UIO_READ;
        auio.uio_rw = UIO_READ;
        auio.uio_segflg = UIO_USERSPACE;
        auio.uio_segflg = UIO_USERSPACE;
#ifndef __ECOS
#ifndef __ECOS
        auio.uio_procp = p;
        auio.uio_procp = p;
#endif
#endif
#ifdef KTRACE
#ifdef KTRACE
        /*
        /*
         * if tracing, save a copy of iovec
         * if tracing, save a copy of iovec
         */
         */
        if (KTRPOINT(p, KTR_GENIO))
        if (KTRPOINT(p, KTR_GENIO))
                ktriov = aiov;
                ktriov = aiov;
#endif
#endif
        cnt = SCARG(uap, nbyte);
        cnt = SCARG(uap, nbyte);
#ifdef __ECOS
#ifdef __ECOS
        error = (*fp->f_ops->fo_read)(fp, &auio);
        error = (*fp->f_ops->fo_read)(fp, &auio);
#else
#else
        error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred);
        error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred);
#endif
#endif
        if (error)
        if (error)
#ifdef __ECOS
#ifdef __ECOS
                if (auio.uio_resid != cnt && (
                if (auio.uio_resid != cnt && (
#else
#else
                if (auio.uio_resid != cnt && (error == ERESTART ||
                if (auio.uio_resid != cnt && (error == ERESTART ||
#endif
#endif
                    error == EINTR || error == EWOULDBLOCK))
                    error == EINTR || error == EWOULDBLOCK))
                        error = 0;
                        error = 0;
        cnt -= auio.uio_resid;
        cnt -= auio.uio_resid;
#ifdef KTRACE
#ifdef KTRACE
        if (KTRPOINT(p, KTR_GENIO) && error == 0)
        if (KTRPOINT(p, KTR_GENIO) && error == 0)
                ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_READ, &ktriov,
                ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_READ, &ktriov,
                    cnt, error);
                    cnt, error);
#endif
#endif
        *retval = cnt;
        *retval = cnt;
        return (error);
        return (error);
}
}
 
 
 
 
#ifndef __ECOS
#ifndef __ECOS
/*
/*
 * Scatter read system call.
 * Scatter read system call.
 */
 */
int
int
sys_readv(p, v, retval)
sys_readv(p, v, retval)
        struct proc *p;
        struct proc *p;
        void *v;
        void *v;
        register_t *retval;
        register_t *retval;
{
{
        register struct sys_readv_args /* {
        register struct sys_readv_args /* {
                syscallarg(int) fd;
                syscallarg(int) fd;
                syscallarg(struct iovec *) iovp;
                syscallarg(struct iovec *) iovp;
                syscallarg(int) iovcnt;
                syscallarg(int) iovcnt;
        } */ *uap = v;
        } */ *uap = v;
        register struct file *fp;
        register struct file *fp;
        register struct filedesc *fdp = p->p_fd;
        register struct filedesc *fdp = p->p_fd;
        struct uio auio;
        struct uio auio;
        register struct iovec *iov;
        register struct iovec *iov;
        struct iovec *needfree;
        struct iovec *needfree;
        struct iovec aiov[UIO_SMALLIOV];
        struct iovec aiov[UIO_SMALLIOV];
        long i, cnt, error = 0;
        long i, cnt, error = 0;
        u_int iovlen;
        u_int iovlen;
#ifdef KTRACE
#ifdef KTRACE
        struct iovec *ktriov = NULL;
        struct iovec *ktriov = NULL;
#endif
#endif
 
 
        if (((u_int)SCARG(uap, fd)) >= fdp->fd_nfiles ||
        if (((u_int)SCARG(uap, fd)) >= fdp->fd_nfiles ||
            (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
            (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
            (fp->f_flag & FREAD) == 0)
            (fp->f_flag & FREAD) == 0)
                return (EBADF);
                return (EBADF);
        if (SCARG(uap, iovcnt) <= 0)
        if (SCARG(uap, iovcnt) <= 0)
                return (EINVAL);
                return (EINVAL);
        /* note: can't use iovlen until iovcnt is validated */
        /* note: can't use iovlen until iovcnt is validated */
        iovlen = SCARG(uap, iovcnt) * sizeof (struct iovec);
        iovlen = SCARG(uap, iovcnt) * sizeof (struct iovec);
        if (SCARG(uap, iovcnt) > UIO_SMALLIOV) {
        if (SCARG(uap, iovcnt) > UIO_SMALLIOV) {
                if (SCARG(uap, iovcnt) > IOV_MAX)
                if (SCARG(uap, iovcnt) > IOV_MAX)
                        return (EINVAL);
                        return (EINVAL);
                MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
                MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
                needfree = iov;
                needfree = iov;
        } else {
        } else {
                iov = aiov;
                iov = aiov;
                needfree = NULL;
                needfree = NULL;
        }
        }
        auio.uio_iov = iov;
        auio.uio_iov = iov;
        auio.uio_iovcnt = SCARG(uap, iovcnt);
        auio.uio_iovcnt = SCARG(uap, iovcnt);
        auio.uio_rw = UIO_READ;
        auio.uio_rw = UIO_READ;
        auio.uio_segflg = UIO_USERSPACE;
        auio.uio_segflg = UIO_USERSPACE;
        auio.uio_procp = p;
        auio.uio_procp = p;
        error = copyin((caddr_t)SCARG(uap, iovp), (caddr_t)iov, iovlen);
        error = copyin((caddr_t)SCARG(uap, iovp), (caddr_t)iov, iovlen);
        if (error)
        if (error)
                goto done;
                goto done;
        auio.uio_resid = 0;
        auio.uio_resid = 0;
        for (i = 0; i < SCARG(uap, iovcnt); i++, iov++) {
        for (i = 0; i < SCARG(uap, iovcnt); i++, iov++) {
                /* Don't allow sum > SSIZE_MAX */
                /* Don't allow sum > SSIZE_MAX */
                if (iov->iov_len > SSIZE_MAX ||
                if (iov->iov_len > SSIZE_MAX ||
                    (auio.uio_resid += iov->iov_len) > SSIZE_MAX) {
                    (auio.uio_resid += iov->iov_len) > SSIZE_MAX) {
                        error = EINVAL;
                        error = EINVAL;
                        goto done;
                        goto done;
                }
                }
        }
        }
#ifdef KTRACE
#ifdef KTRACE
        /*
        /*
         * if tracing, save a copy of iovec
         * if tracing, save a copy of iovec
         */
         */
        if (KTRPOINT(p, KTR_GENIO))  {
        if (KTRPOINT(p, KTR_GENIO))  {
                MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
                MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
                bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
                bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
        }
        }
#endif
#endif
        cnt = auio.uio_resid;
        cnt = auio.uio_resid;
        error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred);
        error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred);
        if (error)
        if (error)
                if (auio.uio_resid != cnt && (error == ERESTART ||
                if (auio.uio_resid != cnt && (error == ERESTART ||
                    error == EINTR || error == EWOULDBLOCK))
                    error == EINTR || error == EWOULDBLOCK))
                        error = 0;
                        error = 0;
        cnt -= auio.uio_resid;
        cnt -= auio.uio_resid;
#ifdef KTRACE
#ifdef KTRACE
        if (ktriov != NULL) {
        if (ktriov != NULL) {
                if (error == 0)
                if (error == 0)
                        ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_READ, ktriov,
                        ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_READ, ktriov,
                            cnt, error);
                            cnt, error);
                FREE(ktriov, M_TEMP);
                FREE(ktriov, M_TEMP);
        }
        }
#endif
#endif
        *retval = cnt;
        *retval = cnt;
done:
done:
        if (needfree)
        if (needfree)
                FREE(needfree, M_IOV);
                FREE(needfree, M_IOV);
        return (error);
        return (error);
}
}
#endif
#endif
 
 
/*
/*
 * Write system call
 * Write system call
 */
 */
#ifdef __ECOS
#ifdef __ECOS
int
int
sys_write(struct sys_write_args *uap, register_t *retval)
sys_write(struct sys_write_args *uap, register_t *retval)
#else
#else
int
int
sys_write(p, v, retval)
sys_write(p, v, retval)
        struct proc *p;
        struct proc *p;
        void *v;
        void *v;
        register_t *retval;
        register_t *retval;
#endif
#endif
{
{
#ifndef __ECOS
#ifndef __ECOS
        register struct sys_write_args /* {
        register struct sys_write_args /* {
                syscallarg(int) fd;
                syscallarg(int) fd;
                syscallarg(void *) buf;
                syscallarg(void *) buf;
                syscallarg(size_t) nbyte;
                syscallarg(size_t) nbyte;
        } */ *uap = v;
        } */ *uap = v;
        register struct filedesc *fdp = p->p_fd;
        register struct filedesc *fdp = p->p_fd;
#endif
#endif
        struct file *fp;
        struct file *fp;
        struct uio auio;
        struct uio auio;
        struct iovec aiov;
        struct iovec aiov;
        long cnt, error = 0;
        long cnt, error = 0;
#ifdef KTRACE
#ifdef KTRACE
        struct iovec ktriov;
        struct iovec ktriov;
#endif
#endif
 
 
#ifdef __ECOS
#ifdef __ECOS
        if (getfp((u_int)SCARG(uap, fd), &fp) ||
        if (getfp((u_int)SCARG(uap, fd), &fp) ||
#else
#else
        if (((u_int)SCARG(uap, fd)) >= fdp->fd_nfiles ||
        if (((u_int)SCARG(uap, fd)) >= fdp->fd_nfiles ||
            (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
            (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
#endif
#endif
            (fp->f_flag & FWRITE) == 0)
            (fp->f_flag & FWRITE) == 0)
                return (EBADF);
                return (EBADF);
        /* Don't allow nbyte to be larger than max return val */
        /* Don't allow nbyte to be larger than max return val */
        if (SCARG(uap, nbyte) > SSIZE_MAX)
        if (SCARG(uap, nbyte) > SSIZE_MAX)
                return(EINVAL);
                return(EINVAL);
        aiov.iov_base = (caddr_t)SCARG(uap, buf);
        aiov.iov_base = (caddr_t)SCARG(uap, buf);
        aiov.iov_len = SCARG(uap, nbyte);
        aiov.iov_len = SCARG(uap, nbyte);
        auio.uio_iov = &aiov;
        auio.uio_iov = &aiov;
        auio.uio_iovcnt = 1;
        auio.uio_iovcnt = 1;
        auio.uio_resid = SCARG(uap, nbyte);
        auio.uio_resid = SCARG(uap, nbyte);
        auio.uio_rw = UIO_WRITE;
        auio.uio_rw = UIO_WRITE;
        auio.uio_segflg = UIO_USERSPACE;
        auio.uio_segflg = UIO_USERSPACE;
#ifndef __ECOS
#ifndef __ECOS
        auio.uio_procp = p;
        auio.uio_procp = p;
#endif
#endif
#ifdef KTRACE
#ifdef KTRACE
        /*
        /*
         * if tracing, save a copy of iovec
         * if tracing, save a copy of iovec
         */
         */
        if (KTRPOINT(p, KTR_GENIO))
        if (KTRPOINT(p, KTR_GENIO))
                ktriov = aiov;
                ktriov = aiov;
#endif
#endif
        cnt = SCARG(uap, nbyte);
        cnt = SCARG(uap, nbyte);
#ifdef __ECOS
#ifdef __ECOS
        error = (*fp->f_ops->fo_write)(fp, &auio);
        error = (*fp->f_ops->fo_write)(fp, &auio);
#else
#else
        error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred);
        error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred);
#endif
#endif
        if (error) {
        if (error) {
#ifdef __ECOS
#ifdef __ECOS
                if (auio.uio_resid != cnt &&
                if (auio.uio_resid != cnt &&
                    (error == EINTR || error == EWOULDBLOCK))
                    (error == EINTR || error == EWOULDBLOCK))
                        error = 0;
                        error = 0;
#else
#else
                if (auio.uio_resid != cnt && (error == ERESTART ||
                if (auio.uio_resid != cnt && (error == ERESTART ||
                    error == EINTR || error == EWOULDBLOCK))
                    error == EINTR || error == EWOULDBLOCK))
                        error = 0;
                        error = 0;
                if (error == EPIPE)
                if (error == EPIPE)
                        psignal(p, SIGPIPE);
                        psignal(p, SIGPIPE);
#endif
#endif
        }
        }
        cnt -= auio.uio_resid;
        cnt -= auio.uio_resid;
#ifdef KTRACE
#ifdef KTRACE
        if (KTRPOINT(p, KTR_GENIO) && error == 0)
        if (KTRPOINT(p, KTR_GENIO) && error == 0)
                ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_WRITE,
                ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_WRITE,
                    &ktriov, cnt, error);
                    &ktriov, cnt, error);
#endif
#endif
        *retval = cnt;
        *retval = cnt;
        return (error);
        return (error);
}
}
 
 
#ifndef __ECOS
#ifndef __ECOS
/*
/*
 * Gather write system call
 * Gather write system call
 */
 */
int
int
sys_writev(p, v, retval)
sys_writev(p, v, retval)
        struct proc *p;
        struct proc *p;
        void *v;
        void *v;
        register_t *retval;
        register_t *retval;
{
{
        register struct sys_writev_args /* {
        register struct sys_writev_args /* {
                syscallarg(int) fd;
                syscallarg(int) fd;
                syscallarg(struct iovec *) iovp;
                syscallarg(struct iovec *) iovp;
                syscallarg(int) iovcnt;
                syscallarg(int) iovcnt;
        } */ *uap = v;
        } */ *uap = v;
        register struct file *fp;
        register struct file *fp;
        register struct filedesc *fdp = p->p_fd;
        register struct filedesc *fdp = p->p_fd;
        struct uio auio;
        struct uio auio;
        register struct iovec *iov;
        register struct iovec *iov;
        struct iovec *needfree;
        struct iovec *needfree;
        struct iovec aiov[UIO_SMALLIOV];
        struct iovec aiov[UIO_SMALLIOV];
        long i, cnt, error = 0;
        long i, cnt, error = 0;
        u_int iovlen;
        u_int iovlen;
#ifdef KTRACE
#ifdef KTRACE
        struct iovec *ktriov = NULL;
        struct iovec *ktriov = NULL;
#endif
#endif
 
 
        if (((u_int)SCARG(uap, fd)) >= fdp->fd_nfiles ||
        if (((u_int)SCARG(uap, fd)) >= fdp->fd_nfiles ||
            (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
            (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
            (fp->f_flag & FWRITE) == 0)
            (fp->f_flag & FWRITE) == 0)
                return (EBADF);
                return (EBADF);
        if (SCARG(uap, iovcnt) <= 0)
        if (SCARG(uap, iovcnt) <= 0)
                return (EINVAL);
                return (EINVAL);
        /* note: can't use iovlen until iovcnt is validated */
        /* note: can't use iovlen until iovcnt is validated */
        iovlen = SCARG(uap, iovcnt) * sizeof (struct iovec);
        iovlen = SCARG(uap, iovcnt) * sizeof (struct iovec);
        if (SCARG(uap, iovcnt) > UIO_SMALLIOV) {
        if (SCARG(uap, iovcnt) > UIO_SMALLIOV) {
                if (SCARG(uap, iovcnt) > IOV_MAX)
                if (SCARG(uap, iovcnt) > IOV_MAX)
                        return (EINVAL);
                        return (EINVAL);
                MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
                MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
                needfree = iov;
                needfree = iov;
        } else {
        } else {
                iov = aiov;
                iov = aiov;
                needfree = NULL;
                needfree = NULL;
        }
        }
        auio.uio_iov = iov;
        auio.uio_iov = iov;
        auio.uio_iovcnt = SCARG(uap, iovcnt);
        auio.uio_iovcnt = SCARG(uap, iovcnt);
        auio.uio_rw = UIO_WRITE;
        auio.uio_rw = UIO_WRITE;
        auio.uio_segflg = UIO_USERSPACE;
        auio.uio_segflg = UIO_USERSPACE;
        auio.uio_procp = p;
        auio.uio_procp = p;
        error = copyin((caddr_t)SCARG(uap, iovp), (caddr_t)iov, iovlen);
        error = copyin((caddr_t)SCARG(uap, iovp), (caddr_t)iov, iovlen);
        if (error)
        if (error)
                goto done;
                goto done;
        auio.uio_resid = 0;
        auio.uio_resid = 0;
        for (i = 0; i < SCARG(uap, iovcnt); i++, iov++) {
        for (i = 0; i < SCARG(uap, iovcnt); i++, iov++) {
                /* Don't allow sum > SSIZE_MAX */
                /* Don't allow sum > SSIZE_MAX */
                if (iov->iov_len > SSIZE_MAX ||
                if (iov->iov_len > SSIZE_MAX ||
                    (auio.uio_resid += iov->iov_len) > SSIZE_MAX) {
                    (auio.uio_resid += iov->iov_len) > SSIZE_MAX) {
                        error = EINVAL;
                        error = EINVAL;
                        goto done;
                        goto done;
                }
                }
        }
        }
#ifdef KTRACE
#ifdef KTRACE
        /*
        /*
         * if tracing, save a copy of iovec
         * if tracing, save a copy of iovec
         */
         */
        if (KTRPOINT(p, KTR_GENIO))  {
        if (KTRPOINT(p, KTR_GENIO))  {
                MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
                MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
                bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
                bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
        }
        }
#endif
#endif
        cnt = auio.uio_resid;
        cnt = auio.uio_resid;
        error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred);
        error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred);
        if (error) {
        if (error) {
                if (auio.uio_resid != cnt && (error == ERESTART ||
                if (auio.uio_resid != cnt && (error == ERESTART ||
                    error == EINTR || error == EWOULDBLOCK))
                    error == EINTR || error == EWOULDBLOCK))
                        error = 0;
                        error = 0;
                if (error == EPIPE)
                if (error == EPIPE)
                        psignal(p, SIGPIPE);
                        psignal(p, SIGPIPE);
        }
        }
        cnt -= auio.uio_resid;
        cnt -= auio.uio_resid;
#ifdef KTRACE
#ifdef KTRACE
        if (ktriov != NULL) {
        if (ktriov != NULL) {
                if (error == 0)
                if (error == 0)
                        ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_WRITE,
                        ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_WRITE,
                                ktriov, cnt, error);
                                ktriov, cnt, error);
                FREE(ktriov, M_TEMP);
                FREE(ktriov, M_TEMP);
        }
        }
#endif
#endif
        *retval = cnt;
        *retval = cnt;
done:
done:
        if (needfree)
        if (needfree)
                FREE(needfree, M_IOV);
                FREE(needfree, M_IOV);
        return (error);
        return (error);
}
}
#endif
#endif
 
 
/*
/*
 * Ioctl system call
 * Ioctl system call
 */
 */
#ifdef __ECOS
#ifdef __ECOS
int
int
sys_ioctl(struct sys_ioctl_args *uap, register_t *retval)
sys_ioctl(struct sys_ioctl_args *uap, register_t *retval)
#else
#else
/* ARGSUSED */
/* ARGSUSED */
int
int
sys_ioctl(p, v, retval)
sys_ioctl(p, v, retval)
        struct proc *p;
        struct proc *p;
        void *v;
        void *v;
        register_t *retval;
        register_t *retval;
#endif
#endif
{
{
#ifndef __ECOS
#ifndef __ECOS
        register struct sys_ioctl_args /* {
        register struct sys_ioctl_args /* {
                syscallarg(int) fd;
                syscallarg(int) fd;
                syscallarg(u_long) com;
                syscallarg(u_long) com;
                syscallarg(caddr_t) data;
                syscallarg(caddr_t) data;
        } */ *uap = v;
        } */ *uap = v;
        register struct filedesc *fdp;
        register struct filedesc *fdp;
#endif
#endif
        int tmp;
        int tmp;
        struct file *fp;
        struct file *fp;
        register u_long com;
        register u_long com;
        register int error;
        register int error;
        register u_int size;
        register u_int size;
        caddr_t data, memp;
        caddr_t data, memp;
#define STK_PARAMS      128
#define STK_PARAMS      128
        char stkbuf[STK_PARAMS];
        char stkbuf[STK_PARAMS];
 
 
#ifdef __ECOS
#ifdef __ECOS
        if (getfp(SCARG(uap, fd), &fp))
        if (getfp(SCARG(uap, fd), &fp))
#else
#else
        fdp = p->p_fd;
        fdp = p->p_fd;
        if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
        if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
            (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
            (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
#endif
#endif
                return (EBADF);
                return (EBADF);
 
 
        if ((fp->f_flag & (FREAD | FWRITE)) == 0)
        if ((fp->f_flag & (FREAD | FWRITE)) == 0)
                return (EBADF);
                return (EBADF);
 
 
#ifdef __ECOS
#ifdef __ECOS
        com = SCARG(uap, com);
        com = SCARG(uap, com);
#else
#else
        switch (com = SCARG(uap, com)) {
        switch (com = SCARG(uap, com)) {
        case FIONCLEX:
        case FIONCLEX:
                fdp->fd_ofileflags[SCARG(uap, fd)] &= ~UF_EXCLOSE;
                fdp->fd_ofileflags[SCARG(uap, fd)] &= ~UF_EXCLOSE;
                return (0);
                return (0);
        case FIOCLEX:
        case FIOCLEX:
                fdp->fd_ofileflags[SCARG(uap, fd)] |= UF_EXCLOSE;
                fdp->fd_ofileflags[SCARG(uap, fd)] |= UF_EXCLOSE;
                return (0);
                return (0);
        }
        }
#endif
#endif
 
 
        /*
        /*
         * Interpret high order word to find amount of data to be
         * Interpret high order word to find amount of data to be
         * copied to/from the user's address space.
         * copied to/from the user's address space.
         */
         */
        size = IOCPARM_LEN(com);
        size = IOCPARM_LEN(com);
#ifndef __ECOS
#ifndef __ECOS
        if (size > IOCPARM_MAX)
        if (size > IOCPARM_MAX)
                return (ENOTTY);
                return (ENOTTY);
#endif
#endif
        memp = NULL;
        memp = NULL;
        if (size > sizeof (stkbuf)) {
        if (size > sizeof (stkbuf)) {
                memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK);
                memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK);
                data = memp;
                data = memp;
        } else
        } else
                data = stkbuf;
                data = stkbuf;
        if (com&IOC_IN) {
        if (com&IOC_IN) {
                if (size) {
                if (size) {
                        error = copyin(SCARG(uap, data), data, (u_int)size);
                        error = copyin(SCARG(uap, data), data, (u_int)size);
                        if (error) {
                        if (error) {
                                if (memp)
                                if (memp)
                                        free(memp, M_IOCTLOPS);
                                        free(memp, M_IOCTLOPS);
                                return (error);
                                return (error);
                        }
                        }
                } else
                } else
                        *(caddr_t *)data = SCARG(uap, data);
                        *(caddr_t *)data = SCARG(uap, data);
        } else if ((com&IOC_OUT) && size)
        } else if ((com&IOC_OUT) && size)
                /*
                /*
                 * Zero the buffer so the user always
                 * Zero the buffer so the user always
                 * gets back something deterministic.
                 * gets back something deterministic.
                 */
                 */
                bzero(data, size);
                bzero(data, size);
        else if (com&IOC_VOID)
        else if (com&IOC_VOID)
                *(caddr_t *)data = SCARG(uap, data);
                *(caddr_t *)data = SCARG(uap, data);
 
 
        switch (com) {
        switch (com) {
 
 
        case FIONBIO:
        case FIONBIO:
                if ((tmp = *(int *)data) != 0)
                if ((tmp = *(int *)data) != 0)
                        fp->f_flag |= FNONBLOCK;
                        fp->f_flag |= FNONBLOCK;
                else
                else
                        fp->f_flag &= ~FNONBLOCK;
                        fp->f_flag &= ~FNONBLOCK;
#ifdef __ECOS
#ifdef __ECOS
                error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (CYG_ADDRWORD)&tmp);
                error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (CYG_ADDRWORD)&tmp);
#else
#else
                error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p);
                error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p);
#endif
#endif
                break;
                break;
 
 
        case FIOASYNC:
        case FIOASYNC:
                if ((tmp = *(int *)data) != 0)
                if ((tmp = *(int *)data) != 0)
                        fp->f_flag |= FASYNC;
                        fp->f_flag |= FASYNC;
                else
                else
                        fp->f_flag &= ~FASYNC;
                        fp->f_flag &= ~FASYNC;
#ifdef __ECOS
#ifdef __ECOS
                error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (CYG_ADDRWORD)&tmp);
                error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (CYG_ADDRWORD)&tmp);
#else
#else
                error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p);
                error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p);
#endif
#endif
                break;
                break;
 
 
#ifndef __ECOS
#ifndef __ECOS
        case FIOSETOWN:
        case FIOSETOWN:
                tmp = *(int *)data;
                tmp = *(int *)data;
                if (fp->f_type == DTYPE_SOCKET) {
                if (fp->f_type == DTYPE_SOCKET) {
                        struct socket *so = (struct socket *)fp->f_data;
                        struct socket *so = (struct socket *)fp->f_data;
 
 
                        so->so_pgid = tmp;
                        so->so_pgid = tmp;
                        so->so_siguid = p->p_cred->p_ruid;
                        so->so_siguid = p->p_cred->p_ruid;
                        so->so_sigeuid = p->p_ucred->cr_uid;
                        so->so_sigeuid = p->p_ucred->cr_uid;
                        error = 0;
                        error = 0;
                        break;
                        break;
                }
                }
                if (tmp <= 0) {
                if (tmp <= 0) {
                        tmp = -tmp;
                        tmp = -tmp;
                } else {
                } else {
                        struct proc *p1 = pfind(tmp);
                        struct proc *p1 = pfind(tmp);
                        if (p1 == 0) {
                        if (p1 == 0) {
                                error = ESRCH;
                                error = ESRCH;
                                break;
                                break;
                        }
                        }
                        tmp = p1->p_pgrp->pg_id;
                        tmp = p1->p_pgrp->pg_id;
                }
                }
                error = (*fp->f_ops->fo_ioctl)
                error = (*fp->f_ops->fo_ioctl)
                        (fp, TIOCSPGRP, (caddr_t)&tmp, p);
                        (fp, TIOCSPGRP, (caddr_t)&tmp, p);
                break;
                break;
 
 
        case FIOGETOWN:
        case FIOGETOWN:
                if (fp->f_type == DTYPE_SOCKET) {
                if (fp->f_type == DTYPE_SOCKET) {
                        error = 0;
                        error = 0;
                        *(int *)data = ((struct socket *)fp->f_data)->so_pgid;
                        *(int *)data = ((struct socket *)fp->f_data)->so_pgid;
                        break;
                        break;
                }
                }
                error = (*fp->f_ops->fo_ioctl)(fp, TIOCGPGRP, data, p);
                error = (*fp->f_ops->fo_ioctl)(fp, TIOCGPGRP, data, p);
                *(int *)data = -*(int *)data;
                *(int *)data = -*(int *)data;
                break;
                break;
#endif
#endif
        default:
        default:
#ifdef __ECOS
#ifdef __ECOS
                error = (*fp->f_ops->fo_ioctl)(fp, com, (CYG_ADDRWORD)data);
                error = (*fp->f_ops->fo_ioctl)(fp, com, (CYG_ADDRWORD)data);
#else
#else
                error = (*fp->f_ops->fo_ioctl)(fp, com, data, p);
                error = (*fp->f_ops->fo_ioctl)(fp, com, data, p);
#endif
#endif
                /*
                /*
                 * Copy any data to user, size was
                 * Copy any data to user, size was
                 * already set and checked above.
                 * already set and checked above.
                 */
                 */
                if (error == 0 && (com&IOC_OUT) && size)
                if (error == 0 && (com&IOC_OUT) && size)
                        error = copyout(data, SCARG(uap, data), (u_int)size);
                        error = copyout(data, SCARG(uap, data), (u_int)size);
                break;
                break;
        }
        }
        if (memp)
        if (memp)
                free(memp, M_IOCTLOPS);
                free(memp, M_IOCTLOPS);
        return (error);
        return (error);
}
}
 
 
#ifndef __ECOS
#ifndef __ECOS
int     selwait, nselcoll;
int     selwait, nselcoll;
 
 
/*
/*
 * Select system call.
 * Select system call.
 */
 */
int
int
sys_select(p, v, retval)
sys_select(p, v, retval)
        register struct proc *p;
        register struct proc *p;
        void *v;
        void *v;
        register_t *retval;
        register_t *retval;
{
{
        register struct sys_select_args /* {
        register struct sys_select_args /* {
                syscallarg(int) nd;
                syscallarg(int) nd;
                syscallarg(fd_set *) in;
                syscallarg(fd_set *) in;
                syscallarg(fd_set *) ou;
                syscallarg(fd_set *) ou;
                syscallarg(fd_set *) ex;
                syscallarg(fd_set *) ex;
                syscallarg(struct timeval *) tv;
                syscallarg(struct timeval *) tv;
        } */ *uap = v;
        } */ *uap = v;
        fd_set bits[6], *pibits[3], *pobits[3];
        fd_set bits[6], *pibits[3], *pobits[3];
        struct timeval atv;
        struct timeval atv;
        int s, ncoll, error = 0, timo;
        int s, ncoll, error = 0, timo;
        u_int ni;
        u_int ni;
 
 
        if (SCARG(uap, nd) > p->p_fd->fd_nfiles) {
        if (SCARG(uap, nd) > p->p_fd->fd_nfiles) {
                /* forgiving; slightly wrong */
                /* forgiving; slightly wrong */
                SCARG(uap, nd) = p->p_fd->fd_nfiles;
                SCARG(uap, nd) = p->p_fd->fd_nfiles;
        }
        }
        ni = howmany(SCARG(uap, nd), NFDBITS) * sizeof(fd_mask);
        ni = howmany(SCARG(uap, nd), NFDBITS) * sizeof(fd_mask);
        if (SCARG(uap, nd) > FD_SETSIZE) {
        if (SCARG(uap, nd) > FD_SETSIZE) {
                caddr_t mbits;
                caddr_t mbits;
 
 
                if ((mbits = malloc(ni * 6, M_TEMP, M_WAITOK)) == NULL) {
                if ((mbits = malloc(ni * 6, M_TEMP, M_WAITOK)) == NULL) {
                        error = EINVAL;
                        error = EINVAL;
                        goto cleanup;
                        goto cleanup;
                }
                }
                bzero(mbits, ni * 6);
                bzero(mbits, ni * 6);
                pibits[0] = (fd_set *)&mbits[ni * 0];
                pibits[0] = (fd_set *)&mbits[ni * 0];
                pibits[1] = (fd_set *)&mbits[ni * 1];
                pibits[1] = (fd_set *)&mbits[ni * 1];
                pibits[2] = (fd_set *)&mbits[ni * 2];
                pibits[2] = (fd_set *)&mbits[ni * 2];
                pobits[0] = (fd_set *)&mbits[ni * 3];
                pobits[0] = (fd_set *)&mbits[ni * 3];
                pobits[1] = (fd_set *)&mbits[ni * 4];
                pobits[1] = (fd_set *)&mbits[ni * 4];
                pobits[2] = (fd_set *)&mbits[ni * 5];
                pobits[2] = (fd_set *)&mbits[ni * 5];
        } else {
        } else {
                bzero((caddr_t)bits, sizeof(bits));
                bzero((caddr_t)bits, sizeof(bits));
                pibits[0] = &bits[0];
                pibits[0] = &bits[0];
                pibits[1] = &bits[1];
                pibits[1] = &bits[1];
                pibits[2] = &bits[2];
                pibits[2] = &bits[2];
                pobits[0] = &bits[3];
                pobits[0] = &bits[3];
                pobits[1] = &bits[4];
                pobits[1] = &bits[4];
                pobits[2] = &bits[5];
                pobits[2] = &bits[5];
        }
        }
 
 
#define getbits(name, x) \
#define getbits(name, x) \
        if (SCARG(uap, name) && (error = copyin((caddr_t)SCARG(uap, name), \
        if (SCARG(uap, name) && (error = copyin((caddr_t)SCARG(uap, name), \
            (caddr_t)pibits[x], ni))) \
            (caddr_t)pibits[x], ni))) \
                goto done;
                goto done;
        getbits(in, 0);
        getbits(in, 0);
        getbits(ou, 1);
        getbits(ou, 1);
        getbits(ex, 2);
        getbits(ex, 2);
#undef  getbits
#undef  getbits
 
 
        if (SCARG(uap, tv)) {
        if (SCARG(uap, tv)) {
                error = copyin((caddr_t)SCARG(uap, tv), (caddr_t)&atv,
                error = copyin((caddr_t)SCARG(uap, tv), (caddr_t)&atv,
                        sizeof (atv));
                        sizeof (atv));
                if (error)
                if (error)
                        goto done;
                        goto done;
                if (itimerfix(&atv)) {
                if (itimerfix(&atv)) {
                        error = EINVAL;
                        error = EINVAL;
                        goto done;
                        goto done;
                }
                }
                s = splclock();
                s = splclock();
                timeradd(&atv, &time, &atv);
                timeradd(&atv, &time, &atv);
                timo = hzto(&atv);
                timo = hzto(&atv);
                /*
                /*
                 * Avoid inadvertently sleeping forever.
                 * Avoid inadvertently sleeping forever.
                 */
                 */
                if (timo == 0)
                if (timo == 0)
                        timo = 1;
                        timo = 1;
                splx(s);
                splx(s);
        } else
        } else
                timo = 0;
                timo = 0;
retry:
retry:
        ncoll = nselcoll;
        ncoll = nselcoll;
        p->p_flag |= P_SELECT;
        p->p_flag |= P_SELECT;
        error = selscan(p, pibits[0], pobits[0], SCARG(uap, nd), retval);
        error = selscan(p, pibits[0], pobits[0], SCARG(uap, nd), retval);
        if (error || *retval)
        if (error || *retval)
                goto done;
                goto done;
        s = splhigh();
        s = splhigh();
        /* this should be timercmp(&time, &atv, >=) */
        /* this should be timercmp(&time, &atv, >=) */
        if (SCARG(uap, tv) && (time.tv_sec > atv.tv_sec ||
        if (SCARG(uap, tv) && (time.tv_sec > atv.tv_sec ||
            (time.tv_sec == atv.tv_sec && time.tv_usec >= atv.tv_usec))) {
            (time.tv_sec == atv.tv_sec && time.tv_usec >= atv.tv_usec))) {
                splx(s);
                splx(s);
                goto done;
                goto done;
        }
        }
        if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
        if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
                splx(s);
                splx(s);
                goto retry;
                goto retry;
        }
        }
        p->p_flag &= ~P_SELECT;
        p->p_flag &= ~P_SELECT;
        error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo);
        error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo);
        splx(s);
        splx(s);
        if (error == 0)
        if (error == 0)
                goto retry;
                goto retry;
done:
done:
        p->p_flag &= ~P_SELECT;
        p->p_flag &= ~P_SELECT;
        /* select is not restarted after signals... */
        /* select is not restarted after signals... */
        if (error == ERESTART)
        if (error == ERESTART)
                error = EINTR;
                error = EINTR;
        if (error == EWOULDBLOCK)
        if (error == EWOULDBLOCK)
                error = 0;
                error = 0;
#define putbits(name, x) \
#define putbits(name, x) \
        if (SCARG(uap, name) && (error2 = copyout((caddr_t)pobits[x], \
        if (SCARG(uap, name) && (error2 = copyout((caddr_t)pobits[x], \
            (caddr_t)SCARG(uap, name), ni))) \
            (caddr_t)SCARG(uap, name), ni))) \
                error = error2;
                error = error2;
        if (error == 0) {
        if (error == 0) {
                int error2;
                int error2;
 
 
                putbits(in, 0);
                putbits(in, 0);
                putbits(ou, 1);
                putbits(ou, 1);
                putbits(ex, 2);
                putbits(ex, 2);
#undef putbits
#undef putbits
        }
        }
 
 
cleanup:
cleanup:
        if (pibits[0] != &bits[0])
        if (pibits[0] != &bits[0])
                free(pibits[0], M_TEMP);
                free(pibits[0], M_TEMP);
        return (error);
        return (error);
}
}
 
 
int
int
selscan(p, ibits, obits, nfd, retval)
selscan(p, ibits, obits, nfd, retval)
        struct proc *p;
        struct proc *p;
        fd_set *ibits, *obits;
        fd_set *ibits, *obits;
        int nfd;
        int nfd;
        register_t *retval;
        register_t *retval;
{
{
        caddr_t cibits = (caddr_t)ibits, cobits = (caddr_t)obits;
        caddr_t cibits = (caddr_t)ibits, cobits = (caddr_t)obits;
        register struct filedesc *fdp = p->p_fd;
        register struct filedesc *fdp = p->p_fd;
        register int msk, i, j, fd;
        register int msk, i, j, fd;
        register fd_mask bits;
        register fd_mask bits;
        struct file *fp;
        struct file *fp;
        int ni, n = 0;
        int ni, n = 0;
        static int flag[3] = { FREAD, FWRITE, 0 };
        static int flag[3] = { FREAD, FWRITE, 0 };
 
 
        /*
        /*
         * if nfd > FD_SETSIZE then the fd_set's contain nfd bits (rounded
         * if nfd > FD_SETSIZE then the fd_set's contain nfd bits (rounded
         * up to the next byte) otherwise the fd_set's are normal sized.
         * up to the next byte) otherwise the fd_set's are normal sized.
         */
         */
        ni = sizeof(fd_set);
        ni = sizeof(fd_set);
        if (nfd > FD_SETSIZE)
        if (nfd > FD_SETSIZE)
                ni = howmany(nfd, NFDBITS) * sizeof(fd_mask);
                ni = howmany(nfd, NFDBITS) * sizeof(fd_mask);
 
 
        for (msk = 0; msk < 3; msk++) {
        for (msk = 0; msk < 3; msk++) {
                fd_set *pibits = (fd_set *)&cibits[msk*ni];
                fd_set *pibits = (fd_set *)&cibits[msk*ni];
                fd_set *pobits = (fd_set *)&cobits[msk*ni];
                fd_set *pobits = (fd_set *)&cobits[msk*ni];
 
 
                for (i = 0; i < nfd; i += NFDBITS) {
                for (i = 0; i < nfd; i += NFDBITS) {
                        bits = pibits->fds_bits[i/NFDBITS];
                        bits = pibits->fds_bits[i/NFDBITS];
                        while ((j = ffs(bits)) && (fd = i + --j) < nfd) {
                        while ((j = ffs(bits)) && (fd = i + --j) < nfd) {
                                bits &= ~(1 << j);
                                bits &= ~(1 << j);
                                fp = fdp->fd_ofiles[fd];
                                fp = fdp->fd_ofiles[fd];
                                if (fp == NULL)
                                if (fp == NULL)
                                        return (EBADF);
                                        return (EBADF);
                                if ((*fp->f_ops->fo_select)(fp, flag[msk], p)) {
                                if ((*fp->f_ops->fo_select)(fp, flag[msk], p)) {
                                        FD_SET(fd, pobits);
                                        FD_SET(fd, pobits);
                                        n++;
                                        n++;
                                }
                                }
                        }
                        }
                }
                }
        }
        }
        *retval = n;
        *retval = n;
        return (0);
        return (0);
}
}
 
 
/*ARGSUSED*/
/*ARGSUSED*/
int
int
seltrue(dev, flag, p)
seltrue(dev, flag, p)
        dev_t dev;
        dev_t dev;
        int flag;
        int flag;
        struct proc *p;
        struct proc *p;
{
{
 
 
        return (1);
        return (1);
}
}
 
 
/*
/*
 * Record a select request.
 * Record a select request.
 */
 */
void
void
selrecord(selector, sip)
selrecord(selector, sip)
        struct proc *selector;
        struct proc *selector;
        struct selinfo *sip;
        struct selinfo *sip;
{
{
        struct proc *p;
        struct proc *p;
        pid_t mypid;
        pid_t mypid;
 
 
        mypid = selector->p_pid;
        mypid = selector->p_pid;
        if (sip->si_selpid == mypid)
        if (sip->si_selpid == mypid)
                return;
                return;
        if (sip->si_selpid && (p = pfind(sip->si_selpid)) &&
        if (sip->si_selpid && (p = pfind(sip->si_selpid)) &&
            p->p_wchan == (caddr_t)&selwait)
            p->p_wchan == (caddr_t)&selwait)
                sip->si_flags |= SI_COLL;
                sip->si_flags |= SI_COLL;
        else
        else
                sip->si_selpid = mypid;
                sip->si_selpid = mypid;
}
}
 
 
/*
/*
 * Do a wakeup when a selectable event occurs.
 * Do a wakeup when a selectable event occurs.
 */
 */
void
void
selwakeup(sip)
selwakeup(sip)
        register struct selinfo *sip;
        register struct selinfo *sip;
{
{
        register struct proc *p;
        register struct proc *p;
        int s;
        int s;
 
 
        if (sip->si_selpid == 0)
        if (sip->si_selpid == 0)
                return;
                return;
        if (sip->si_flags & SI_COLL) {
        if (sip->si_flags & SI_COLL) {
                nselcoll++;
                nselcoll++;
                sip->si_flags &= ~SI_COLL;
                sip->si_flags &= ~SI_COLL;
                wakeup((caddr_t)&selwait);
                wakeup((caddr_t)&selwait);
        }
        }
        p = pfind(sip->si_selpid);
        p = pfind(sip->si_selpid);
        sip->si_selpid = 0;
        sip->si_selpid = 0;
        if (p != NULL) {
        if (p != NULL) {
                s = splhigh();
                s = splhigh();
                if (p->p_wchan == (caddr_t)&selwait) {
                if (p->p_wchan == (caddr_t)&selwait) {
                        if (p->p_stat == SSLEEP)
                        if (p->p_stat == SSLEEP)
                                setrunnable(p);
                                setrunnable(p);
                        else
                        else
                                unsleep(p);
                                unsleep(p);
                } else if (p->p_flag & P_SELECT)
                } else if (p->p_flag & P_SELECT)
                        p->p_flag &= ~P_SELECT;
                        p->p_flag &= ~P_SELECT;
                splx(s);
                splx(s);
        }
        }
}
}
 
 
void
void
pollscan(p, pl, nfd, retval)
pollscan(p, pl, nfd, retval)
        struct proc *p;
        struct proc *p;
        struct pollfd *pl;
        struct pollfd *pl;
        int nfd;
        int nfd;
        register_t *retval;
        register_t *retval;
{
{
        register struct filedesc *fdp = p->p_fd;
        register struct filedesc *fdp = p->p_fd;
        register int msk, i;
        register int msk, i;
        struct file *fp;
        struct file *fp;
        int x, n = 0;
        int x, n = 0;
        static int flag[3] = { FREAD, FWRITE, 0 };
        static int flag[3] = { FREAD, FWRITE, 0 };
        static int pflag[3] = { POLLIN|POLLRDNORM, POLLOUT, POLLERR };
        static int pflag[3] = { POLLIN|POLLRDNORM, POLLOUT, POLLERR };
 
 
        /*
        /*
         * XXX: We need to implement the rest of the flags.
         * XXX: We need to implement the rest of the flags.
         */
         */
        for (i = 0; i < nfd; i++) {
        for (i = 0; i < nfd; i++) {
                /* Check the file descriptor. */
                /* Check the file descriptor. */
                if (pl[i].fd < 0)
                if (pl[i].fd < 0)
                        continue;
                        continue;
                if (pl[i].fd >= fdp->fd_nfiles) {
                if (pl[i].fd >= fdp->fd_nfiles) {
                        pl[i].revents = POLLNVAL;
                        pl[i].revents = POLLNVAL;
                        n++;
                        n++;
                        continue;
                        continue;
                }
                }
 
 
                fp = fdp->fd_ofiles[pl[i].fd];
                fp = fdp->fd_ofiles[pl[i].fd];
                if (fp == NULL) {
                if (fp == NULL) {
                        pl[i].revents = POLLNVAL;
                        pl[i].revents = POLLNVAL;
                        n++;
                        n++;
                        continue;
                        continue;
                }
                }
                for (x = msk = 0; msk < 3; msk++) {
                for (x = msk = 0; msk < 3; msk++) {
                        if (pl[i].events & pflag[msk]) {
                        if (pl[i].events & pflag[msk]) {
                                if ((*fp->f_ops->fo_select)(fp, flag[msk], p)) {
                                if ((*fp->f_ops->fo_select)(fp, flag[msk], p)) {
                                        pl[i].revents |= pflag[msk] &
                                        pl[i].revents |= pflag[msk] &
                                            pl[i].events;
                                            pl[i].events;
                                        x++;
                                        x++;
                                }
                                }
                        }
                        }
                }
                }
                if (x)
                if (x)
                        n++;
                        n++;
        }
        }
        *retval = n;
        *retval = n;
}
}
 
 
/*
/*
 * We are using the same mechanism as select only we encode/decode args
 * We are using the same mechanism as select only we encode/decode args
 * differently.
 * differently.
 */
 */
int
int
sys_poll(p, v, retval)
sys_poll(p, v, retval)
        register struct proc *p;
        register struct proc *p;
        void *v;
        void *v;
        register_t *retval;
        register_t *retval;
{
{
        struct sys_poll_args *uap = v;
        struct sys_poll_args *uap = v;
        size_t sz;
        size_t sz;
        struct pollfd pfds[4], *pl = pfds;
        struct pollfd pfds[4], *pl = pfds;
        int msec = SCARG(uap, timeout);
        int msec = SCARG(uap, timeout);
        struct timeval atv;
        struct timeval atv;
        int timo, ncoll, i, s, error, error2;
        int timo, ncoll, i, s, error, error2;
        extern int nselcoll, selwait;
        extern int nselcoll, selwait;
 
 
        /* Standards say no more than MAX_OPEN; this is possibly better. */
        /* Standards say no more than MAX_OPEN; this is possibly better. */
        if (SCARG(uap, nfds) > min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur,
        if (SCARG(uap, nfds) > min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur,
            maxfiles))
            maxfiles))
                return (EINVAL);
                return (EINVAL);
 
 
        sz = sizeof(struct pollfd) * SCARG(uap, nfds);
        sz = sizeof(struct pollfd) * SCARG(uap, nfds);
 
 
        /* optimize for the default case, of a small nfds value */
        /* optimize for the default case, of a small nfds value */
        if (sz > sizeof(pfds))
        if (sz > sizeof(pfds))
                pl = (struct pollfd *) malloc(sz, M_TEMP, M_WAITOK);
                pl = (struct pollfd *) malloc(sz, M_TEMP, M_WAITOK);
 
 
        if ((error = copyin(SCARG(uap, fds), pl, sz)) != 0)
        if ((error = copyin(SCARG(uap, fds), pl, sz)) != 0)
                goto bad;
                goto bad;
 
 
        for (i = 0; i < SCARG(uap, nfds); i++)
        for (i = 0; i < SCARG(uap, nfds); i++)
                pl[i].revents = 0;
                pl[i].revents = 0;
 
 
        if (msec != -1) {
        if (msec != -1) {
                atv.tv_sec = msec / 1000;
                atv.tv_sec = msec / 1000;
                atv.tv_usec = (msec - (atv.tv_sec * 1000)) * 1000;
                atv.tv_usec = (msec - (atv.tv_sec * 1000)) * 1000;
 
 
                if (itimerfix(&atv)) {
                if (itimerfix(&atv)) {
                        error = EINVAL;
                        error = EINVAL;
                        goto done;
                        goto done;
                }
                }
                s = splclock();
                s = splclock();
                timeradd(&atv, &time, &atv);
                timeradd(&atv, &time, &atv);
                timo = hzto(&atv);
                timo = hzto(&atv);
                /*
                /*
                 * Avoid inadvertently sleeping forever.
                 * Avoid inadvertently sleeping forever.
                 */
                 */
                if (timo == 0)
                if (timo == 0)
                        timo = 1;
                        timo = 1;
                splx(s);
                splx(s);
        } else
        } else
                timo = 0;
                timo = 0;
 
 
retry:
retry:
        ncoll = nselcoll;
        ncoll = nselcoll;
        p->p_flag |= P_SELECT;
        p->p_flag |= P_SELECT;
        pollscan(p, pl, SCARG(uap, nfds), retval);
        pollscan(p, pl, SCARG(uap, nfds), retval);
        if (*retval)
        if (*retval)
                goto done;
                goto done;
        s = splhigh();
        s = splhigh();
        if (timo && timercmp(&time, &atv, >=)) {
        if (timo && timercmp(&time, &atv, >=)) {
                splx(s);
                splx(s);
                goto done;
                goto done;
        }
        }
        if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
        if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
                splx(s);
                splx(s);
                goto retry;
                goto retry;
        }
        }
        p->p_flag &= ~P_SELECT;
        p->p_flag &= ~P_SELECT;
        error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "poll", timo);
        error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "poll", timo);
        splx(s);
        splx(s);
        if (error == 0)
        if (error == 0)
                goto retry;
                goto retry;
 
 
done:
done:
        p->p_flag &= ~P_SELECT;
        p->p_flag &= ~P_SELECT;
        /* poll is not restarted after signals... */
        /* poll is not restarted after signals... */
        if (error == ERESTART)
        if (error == ERESTART)
                error = EINTR;
                error = EINTR;
        if (error == EWOULDBLOCK)
        if (error == EWOULDBLOCK)
                error = 0;
                error = 0;
        if ((error2 = copyout(pl, SCARG(uap, fds), sz)) != 0)
        if ((error2 = copyout(pl, SCARG(uap, fds), sz)) != 0)
                error = error2;
                error = error2;
bad:
bad:
        if (pl != pfds)
        if (pl != pfds)
                free((char *) pl, M_TEMP);
                free((char *) pl, M_TEMP);
        return (error);
        return (error);
}
}
#endif
#endif
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.