Source-Changes-HG archive

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

[src/trunk]: src/sys/compat/linux/common Pass SIOC* calls that are done on de...



details:   https://anonhg.NetBSD.org/src/rev/47346d67baa2
branches:  trunk
changeset: 500770:47346d67baa2
user:      fvdl <fvdl%NetBSD.org@localhost>
date:      Mon Dec 18 14:46:36 2000 +0000

description:
Pass SIOC* calls that are done on devices (not sockets) through
without trying to interpret done, as is done on Linux. The device
will get them as PTIOCLINUX, with command and arg in the structure
passed in.

diffstat:

 sys/compat/linux/common/linux_socket.c |  57 ++++++++++++++++++++++++++++++---
 1 files changed, 51 insertions(+), 6 deletions(-)

diffs (90 lines):

diff -r 1c99beef0bb9 -r 47346d67baa2 sys/compat/linux/common/linux_socket.c
--- a/sys/compat/linux/common/linux_socket.c    Mon Dec 18 14:44:44 2000 +0000
+++ b/sys/compat/linux/common/linux_socket.c    Mon Dec 18 14:46:36 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: linux_socket.c,v 1.24 2000/05/03 21:41:43 thorpej Exp $        */
+/*     $NetBSD: linux_socket.c,v 1.25 2000/12/18 14:46:36 fvdl Exp $   */
 
 /*-
  * Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
@@ -597,7 +597,41 @@
        register_t *retval;
 {
        u_long com;
+       int error = 0, isdev = 0, dosys = 1;
        struct sys_ioctl_args ia;
+       struct file *fp;
+       struct filedesc *fdp;
+       struct vnode *vp;
+       int (*ioctlf) __P((struct file *, u_long, caddr_t, struct proc *));
+       struct ioctl_pt pt;
+
+        fdp = p->p_fd;
+       if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
+           (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
+           (fp->f_iflags & FIF_WANTCLOSE) != 0)
+               return (EBADF);
+
+       FILE_USE(fp);
+
+       if (fp->f_type == DTYPE_VNODE) {
+               vp = (struct vnode *)fp->f_data;
+               isdev = vp->v_type == VCHR;
+       }
+
+       /*
+        * Don't try to interpret socket ioctl calls that are done
+        * on a device filedescriptor, just pass them through, to
+        * emulate Linux behaviour. Use PTIOCLINUX so that the
+        * device will only handle these if it's prepared to do
+        * so, to avoid unexpected things from happening.
+        */
+       if (isdev) {
+               ioctlf = fp->f_ops->fo_ioctl;
+               pt.com = SCARG(uap, com);
+               pt.data = SCARG(uap, data);
+               error = ioctlf(fp, PTIOCLINUX, (caddr_t)&pt, p);
+               goto out;
+       }
 
        com = SCARG(uap, com);
        retval[0] = 0;
@@ -609,6 +643,9 @@
        case LINUX_SIOCGIFFLAGS:
                SCARG(&ia, com) = SIOCGIFFLAGS;
                break;
+       case LINUX_SIOCSIFFLAGS:
+               SCARG(&ia, com) = SIOCSIFFLAGS;
+               break;
        case LINUX_SIOCGIFADDR:
                SCARG(&ia, com) = OSIOCGIFADDR;
                break;
@@ -628,15 +665,23 @@
                SCARG(&ia, com) = SIOCDELMULTI;
                break;
        case LINUX_SIOCGIFHWADDR:
-               return linux_getifhwaddr(p, retval, SCARG(uap, fd),
+               error = linux_getifhwaddr(p, retval, SCARG(uap, fd),
                                         SCARG(uap, data));
+               break;
        default:
-               return EINVAL;
+               error = EINVAL;
        }
 
-       SCARG(&ia, fd) = SCARG(uap, fd);
-       SCARG(&ia, data) = SCARG(uap, data);
-       return sys_ioctl(p, &ia, retval);
+out:
+       FILE_UNUSE(fp, p);
+
+       if (error ==0 && dosys) {
+               SCARG(&ia, fd) = SCARG(uap, fd);
+               SCARG(&ia, data) = SCARG(uap, data);
+               error = sys_ioctl(p, &ia, retval);
+       }
+
+       return error;
 }
 
 int



Home | Main Index | Thread Index | Old Index