]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/netat/sys_dep.c
xnu-792.22.5.tar.gz
[apple/xnu.git] / bsd / netat / sys_dep.c
index a5d17dc846675198ed076981cd880330d25e746d..ece349050b814200ab2f733951c0c78d5c34ed79 100644 (file)
@@ -1,23 +1,29 @@
 /*
  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
  *
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  * 
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /*
  *     Copyright (c) 1995-1998 Apple Computer, Inc. 
 #include <machine/spl.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
-#include <sys/proc.h>
+#include <sys/proc_internal.h> /* for p_fd in fdflags */
 #include <sys/filedesc.h>
 #include <sys/fcntl.h>
 #include <sys/mbuf.h>
 #include <sys/malloc.h>
-#include <sys/file.h>
+#include <sys/file_internal.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
+#include <sys/sysproto.h>
+#include <sys/kdebug.h>
 #include <net/if_var.h>
 
 #include <netat/sysglue.h>
 #include <netat/at_pcb.h>
 #include <netat/debug.h>
 
-int (*sys_ATsocket)() = 0;
-int (*sys_ATgetmsg)() = 0;
-int (*sys_ATputmsg)() = 0;
-int (*sys_ATPsndreq)() = 0;
-int (*sys_ATPsndrsp)() = 0;
-int (*sys_ATPgetreq)() = 0;
-int (*sys_ATPgetrsp)() = 0;
 
 extern at_state_t at_state;    /* global state of AT network */
 extern at_ifaddr_t *ifID_home; /* default interface */
+extern lck_mtx_t * atalk_mutex;
+
+#define f_flag f_fglob->fg_flag
+#define f_type f_fglob->fg_type
+#define f_msgcount f_fglob->fg_msgcount
+#define f_cred f_fglob->fg_cred
+#define f_ops f_fglob->fg_ops
+#define f_offset f_fglob->fg_offset
+#define f_data f_fglob->fg_data
+
+extern int _ATsocket(int, int *, void *);
+extern int _ATgetmsg(int, strbuf_t *, strbuf_t *, int *, int *, void *);
+extern int _ATputmsg();
+extern int _ATPsndreq(), _ATPsndrsp(), _ATPgetreq(), _ATPgetrsp();
+
 
 int ATsocket(proc, uap, retval)
-       void *proc;
-       struct {
-         int proto;
-       } *uap;
+       struct proc *proc;
+       struct ATsocket_args *uap;
        int *retval;
 {
        int err;
-
-       if (sys_ATsocket) {
+       atalk_lock();
+       if (_ATsocket) {
                /* required check for all AppleTalk system calls */
                if (!(at_state.flags & AT_ST_STARTED) || !ifID_home) {
                        *retval = -1;
                        err = ENOTREADY;
                } else {
-                       *retval = (*sys_ATsocket)(uap->proto, &err, proc);
+                       *retval = _ATsocket((int)uap->proto, (int *)&err, (void *)proc);
                }
        } else {
                *retval = -1;
                err = ENXIO;
        }
+       atalk_unlock();
        return err;
 }
 
 int ATgetmsg(proc, uap, retval)
-       void *proc;
-       struct {
-         int fd;
-         void *ctlptr;
-         void *datptr;
-         int *flags;
-       } *uap;
+       struct proc *proc;
+       struct ATgetmsg_args *uap;
        int *retval;
 {
        int err;
 
-       if (sys_ATgetmsg) {
+       atalk_lock();
+       if (_ATgetmsg) {
                /* required check for all AppleTalk system calls */
                if (!(at_state.flags & AT_ST_STARTED) || !ifID_home) {
                        *retval = -1;
                        err = ENOTREADY;
                } else {
                        *retval = 
-                         (*sys_ATgetmsg)(uap->fd, uap->ctlptr, uap->datptr, 
+                         (*_ATgetmsg)(uap->fd, uap->ctlptr, uap->datptr, 
                                          uap->flags, &err, proc);
                }
        } else {
                *retval = -1;
                err = ENXIO;
        }
+       atalk_unlock();
        return err;
 }
 
 int ATputmsg(proc, uap, retval)
-       void *proc;
-       struct {
-       int fd;
-       void *ctlptr;
-       void *datptr;
-       int flags;
-       } *uap;
+       struct proc *proc;
+       struct ATputmsg_args *uap;
        int *retval;
 {
        int err;
 
-       if (sys_ATputmsg) {
+       atalk_lock();
+       if (_ATputmsg) {
                /* required check for all AppleTalk system calls */
                if (!(at_state.flags & AT_ST_STARTED) || !ifID_home) {
                        *retval = -1;
                        err = ENOTREADY;
                } else {
                        *retval = 
-                         (*sys_ATputmsg)(uap->fd, uap->ctlptr, uap->datptr, 
+                         _ATputmsg(uap->fd, uap->ctlptr, uap->datptr, 
                                          uap->flags, &err, proc);
                }
        } else {
                *retval = -1;
                err = ENXIO;
        }
+       atalk_unlock();
        return err;
 }
 
 int ATPsndreq(proc, uap, retval)
-       void *proc;
-       struct {
-         int fd;
-         unsigned char *buf;
-         int len;
-         int nowait;
-       } *uap;
+       struct proc *proc;
+       struct ATPsndreq_args *uap;
        int *retval;
 {
        int err;
 
-       if (sys_ATPsndreq) {
+       atalk_lock();
+       if (_ATPsndreq) {
                /* required check for all AppleTalk system calls */
                if (!(at_state.flags & AT_ST_STARTED) || !ifID_home) {
                        *retval = -1;
                        err = ENOTREADY;
                } else {
                        *retval = 
-                         (*sys_ATPsndreq)(uap->fd, uap->buf, uap->len, 
+                         _ATPsndreq(uap->fd, uap->buf, uap->len, 
                                           uap->nowait, &err, proc);
                }
        } else {
                *retval = -1;
                err= ENXIO;
        }
+       atalk_unlock();
        return err;
 }
 
 int ATPsndrsp(proc, uap, retval)
-       void *proc;
-       struct {
-         int fd;
-         unsigned char *respbuff;
-         int resplen;
-         int datalen;
-       } *uap;
+       struct proc *proc;
+       struct ATPsndrsp_args *uap;
        int *retval;
 {
        int err;
 
-       if (sys_ATPsndrsp) {
+       atalk_lock();
+       if (_ATPsndrsp) {
                /* required check for all AppleTalk system calls */
                if (!(at_state.flags & AT_ST_STARTED) || !ifID_home) {
                        *retval = -1;
                        err = ENOTREADY;
                } else { 
                        *retval = 
-                         (*sys_ATPsndrsp)(uap->fd, uap->respbuff, 
+                         _ATPsndrsp(uap->fd, uap->respbuff, 
                                           uap->resplen, uap->datalen, &err, proc);
                }
        } else {
                *retval = -1;
                err = ENXIO;
        }
+       atalk_unlock();
        return err;
 }
 
 int ATPgetreq(proc, uap, retval)
-       void *proc;
-       struct {
-         int fd;
-         unsigned char *buf;
-         int buflen;
-       } *uap;
+       struct proc *proc;
+       struct ATPgetreq_args *uap;
        int *retval;
 {
        int err;
 
-       if (sys_ATPgetreq) {
+       atalk_lock();
+       if (_ATPgetreq) {
                /* required check for all AppleTalk system calls */
                if (!(at_state.flags & AT_ST_STARTED) || !ifID_home) {
                        *retval = -1;
                        err = ENOTREADY;
                } else {
                        *retval = 
-                         (*sys_ATPgetreq)(uap->fd, uap->buf, uap->buflen, 
+                         _ATPgetreq(uap->fd, uap->buf, uap->buflen, 
                                           &err, proc);
                }
        } else {
                *retval = -1;
                err = ENXIO;
        }
+       atalk_unlock();
        return err;
 }
 
 int ATPgetrsp(proc, uap, retval)
-       void *proc;
-       struct {
-         int fd;
-         unsigned char *bdsp;
-       } *uap;
+       struct proc *proc;
+       struct ATPgetrsp_args *uap;
        int *retval;
 {
        int err = 0;
 
-       if (sys_ATPgetrsp) {
+       atalk_lock();
+       if (_ATPgetrsp) {
                /* required check for all AppleTalk system calls */
                if (!(at_state.flags & AT_ST_STARTED) || !ifID_home) {
                        *retval = -1;
                        err = ENOTREADY;
                } else {
                        *retval = 
-                         (*sys_ATPgetrsp)(uap->fd, uap->bdsp, &err, proc);
+                         _ATPgetrsp(uap->fd, uap->bdsp, &err, proc);
                }
        } else {
                *retval = -1;
                err = ENXIO;
        }
+       atalk_unlock();
        return err;
 }
 
-int atalk_closeref(fp, grefp)
-       struct file *fp;
+int atalk_closeref(fg, grefp)
+       struct fileglob *fg;
        gref_t **grefp;
 {
-       if ((*grefp = (gref_t *)fp->f_data)) {
-               fp->f_data = 0;
-/*
-               kprintf("atalk_closeref: fp = 0x%x, gref = 0x%x\n", (u_int)fp, 
-                       (u_int)*grefp);
-*/
+       if ((*grefp = (gref_t *)fg->fg_data)) {
+               fg->fg_data = 0;
                return(0);
        }
        return(EBADF);
@@ -274,16 +270,17 @@ int atalk_openref(gref, retfd, proc)
        int *retfd;
        struct proc *proc;
 {
-       extern int _ATread(), _ATwrite(),_ATioctl(), _ATselect(), _ATclose();
+       extern int _ATread(), _ATwrite(),_ATioctl(), _ATselect(), _ATclose(), _ATkqfilter();
        static struct fileops fileops = 
-               {_ATread, _ATwrite, _ATioctl, _ATselect, _ATclose};
+               {_ATread, _ATwrite, _ATioctl, _ATselect, _ATclose, _ATkqfilter, 0};
        int err, fd;
-       struct file *fp;
-
-       thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
-
-       if ((err = falloc(proc, &fp, &fd)) != 0) {
-            thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
+       struct fileproc *fp;
+       
+       lck_mtx_assert(atalk_mutex, LCK_MTX_ASSERT_OWNED);
+       
+       proc_fdlock(proc);
+       if ((err = falloc_locked(proc, &fp, &fd, 1)) != 0) {
+               proc_fdunlock(proc);
                return err;
        }
 
@@ -293,44 +290,69 @@ int atalk_openref(gref, retfd, proc)
         */
        fp->f_type = DTYPE_ATALK+1;
        fp->f_ops = &fileops;
+       fp->f_data = (void *)gref;
+
        *fdflags(proc, fd) &= ~UF_RESERVED;
        *retfd = fd;
-       fp->f_data = (void *)gref;
+       fp_drop(proc, fd, fp, 1);
+       proc_fdunlock(proc);
 /*
        kprintf("atalk_openref: fp = 0x%x, gref = 0x%x\n", (u_int)fp, (u_int)gref);
 */
-       thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
        return 0;
 }
 
-/* go from file descriptor to gref, which has been saved in fp->f_data */
-int atalk_getref(fp, fd, grefp, proc)
-struct file *fp;
+/* 
+ * go from file descriptor to gref, which has been saved in fp->f_data 
+ *
+ * This routine returns with an iocount on the fileproc when the fp is null
+ * as it converts fd to fileproc. Callers of this api who pass fp as null
+ * need to drop the iocount when they are done with the fp
+ */
+int atalk_getref(fp, fd, grefp, proc, droponerr)
+struct fileproc *fp;
 int fd;
 gref_t **grefp;
 struct proc *proc;
+int droponerr;
 {
-     thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
-     if (fp == 0) {
-         int error = fdgetf(proc, fd, &fp);
-
-         if (error) {
-              
-              *grefp = (gref_t *) 0;
-              thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
-              return EBADF;
-         }
-     }
-     if ((*grefp = (gref_t *)fp->f_data) == 0) {
-         thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
-         return EBADF;
-     }
+       int error;
 
-     if ((*grefp)->errno) {
-         thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
-         return (int)(*grefp)->errno;
-     }
+       proc_fdlock(proc);
+       error = atalk_getref_locked(fp, fd, grefp, proc, droponerr);
+       proc_fdunlock(proc);
+       return error;
+}
 
-     thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
-     return 0;
+int atalk_getref_locked(fp, fd, grefp, proc, droponerr)
+struct fileproc *fp;
+int fd;
+gref_t **grefp;
+struct proc *proc;
+int droponerr;
+{
+       lck_mtx_assert(atalk_mutex, LCK_MTX_ASSERT_OWNED);
+       if (fp == 0) {
+               int error = fp_lookup(proc, fd, &fp, 1);
+       
+               if (error) {
+                  
+                       *grefp = (gref_t *) 0;
+                  return EBADF;
+               }
+       }
+       *grefp = (gref_t *)fp->f_data;
+       if (fp->f_type != (DTYPE_ATALK+1) || *grefp == 0 || *grefp == (gref_t *)(-1)) {
+               if (droponerr)
+                       fp_drop(proc, fd, fp, 1);
+               printf("atalk_getref_locked EBADF f_data: %x\n", fp->f_data);
+               return EBADF;
+       }
+       
+       if ((*grefp)->errno) {
+               if (droponerr)
+                       fp_drop(proc, fd, fp, 1);
+               return (int)(*grefp)->errno;
+       }
+       return 0;
 }