X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/1c79356b52d46aa6b508fb032f5ae709b1f2897b..4452a7af2eac33dbad800bcc91f2399d62c18f53:/bsd/netat/sys_dep.c diff --git a/bsd/netat/sys_dep.c b/bsd/netat/sys_dep.c index a5d17dc84..ece349050 100644 --- a/bsd/netat/sys_dep.c +++ b/bsd/netat/sys_dep.c @@ -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. @@ -33,14 +39,16 @@ #include #include #include -#include +#include /* for p_fd in fdflags */ #include #include #include #include -#include +#include #include #include +#include +#include #include #include @@ -49,221 +57,209 @@ #include #include -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; }