]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/netat/sys_dep.c
xnu-1228.0.2.tar.gz
[apple/xnu.git] / bsd / netat / sys_dep.c
index 55b12d8a7ba429b8f42c074d0755122b4f35b031..47a18d89c4f5cf6aecacd811e235e05e23bad1f0 100644 (file)
@@ -1,16 +1,19 @@
 /*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1995-2007 Apple Inc. All rights reserved.
  *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
  * 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. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
+ * 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.
+ * 
+ * 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
  * 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. 
- *
  *  Change Log:
  *    Created February 20, 1995 by Tuyen Nguyen
  *    Modified for MP, 1996 by Tuyen Nguyen
 #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/appletalk.h>
-#include <netat/at_var.h>
 #include <netat/at_pcb.h>
+#include <netat/at_var.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;
+int falloc_locked(proc_t, struct fileproc **, int *, vfs_context_t, int);
 
-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
+
+
+int _ATkqfilter(struct fileproc *, struct knote *, vfs_context_t);
+int _ATselect(struct fileproc *, int, void *, vfs_context_t);
+int _ATioctl(struct fileproc *, u_long, caddr_t, vfs_context_t);
+int _ATwrite(struct fileproc *, struct uio *, int, vfs_context_t);
+int _ATread(struct fileproc *, struct uio *, int, vfs_context_t);
+int _ATclose(struct fileglob *, vfs_context_t);
 
-struct ATsocket_args {
-    int proto;
-};
 int ATsocket(proc, uap, retval)
-       void *proc;
+       struct proc *proc;
        struct ATsocket_args *uap;
        int *retval;
 {
        int err;
-
-       if (sys_ATsocket) {
+       atalk_lock();
+       if (1 /* _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;
 }
 
-struct ATgetmsg_args {
-    int fd;
-    void *ctlptr;
-    void *datptr;
-    int *flags;
-};
 int ATgetmsg(proc, uap, retval)
-       void *proc;
+       struct proc *proc;
        struct ATgetmsg_args *uap;
        int *retval;
 {
        int err;
 
-       if (sys_ATgetmsg) {
+       atalk_lock();
+       if (1 /* _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;
 }
 
-struct ATputmsg_args {
-       int fd;
-       void *ctlptr;
-       void *datptr;
-       int flags;
-};
 int ATputmsg(proc, uap, retval)
-       void *proc;
+       struct proc *proc;
        struct ATputmsg_args *uap;
        int *retval;
 {
        int err;
 
-       if (sys_ATputmsg) {
+       atalk_lock();
+       if (1 /* _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;
 }
 
-struct ATPsndreq_args {
-    int fd;
-    unsigned char *buf;
-    int len;
-    int nowait;
-};
 int ATPsndreq(proc, uap, retval)
-       void *proc;
+       struct proc *proc;
        struct ATPsndreq_args *uap;
        int *retval;
 {
        int err;
 
-       if (sys_ATPsndreq) {
+       atalk_lock();
+       if (1 /* _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;
 }
 
-struct ATPsndrsp_args {
-         int fd;
-         unsigned char *respbuff;
-         int resplen;
-         int datalen;
-};
 int ATPsndrsp(proc, uap, retval)
-       void *proc;
+       struct proc *proc;
        struct ATPsndrsp_args *uap;
        int *retval;
 {
        int err;
 
-       if (sys_ATPsndrsp) {
+       atalk_lock();
+       if (1 /*_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;
 }
 
-struct ATPgetreq_args {
-         int fd;
-         unsigned char *buf;
-         int buflen;
-};
 int ATPgetreq(proc, uap, retval)
-       void *proc;
+       struct proc *proc;
        struct ATPgetreq_args *uap;
        int *retval;
 {
        int err;
 
-       if (sys_ATPgetreq) {
+       atalk_lock();
+       if (1 /* _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;
 }
 
-struct ATPgetrsp_args {
-         int fd;
-         unsigned char *bdsp;
-};
 int ATPgetrsp(proc, uap, retval)
-       void *proc;
+       struct proc *proc;
        struct ATPgetrsp_args *uap;
        int *retval;
 {
        int err = 0;
 
-       if (sys_ATPgetrsp) {
+       atalk_lock();
+       if (1 /*_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, (struct atpBDS *)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);
@@ -284,16 +270,16 @@ int atalk_openref(gref, retfd, proc)
        int *retfd;
        struct proc *proc;
 {
-       extern int _ATread(), _ATwrite(),_ATioctl(), _ATselect(), _ATclose(), _ATkqfilter();
        static struct fileops fileops = 
-               {_ATread, _ATwrite, _ATioctl, _ATselect, _ATclose, _ATkqfilter};
+               {_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, vfs_context_current(), 1)) != 0) {
+               proc_fdunlock(proc);
                return err;
        }
 
@@ -303,45 +289,69 @@ int atalk_openref(gref, retfd, proc)
         */
        fp->f_type = DTYPE_ATALK+1;
        fp->f_ops = &fileops;
-       *fdflags(proc, fd) &= ~UF_RESERVED;
-       *retfd = fd;
        fp->f_data = (void *)gref;
+
+       procfdtbl_releasefd(proc, fd, NULL);
+       *retfd = fd;
+       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);
+       int error;
 
-         if (error) {
-              
-              *grefp = (gref_t *) 0;
-              thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
-              return EBADF;
-         }
-     }
-     *grefp = (gref_t *)fp->f_data;
-     if (*grefp == 0 || *grefp == (gref_t *)(-1)) {
-         thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
-         return EBADF;
-     }
-
-     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: %p\n", fp->f_data);
+               return EBADF;
+       }
+       
+       if ((*grefp)->errno) {
+               if (droponerr)
+                       fp_drop(proc, fd, fp, 1);
+               return (int)(*grefp)->errno;
+       }
+       return 0;
 }