The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/freebsd/freebsd_sysctl.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: freebsd_sysctl.c,v 1.14 2008/04/28 20:23:41 martin Exp $       */
    2 
    3 /*-
    4  * Copyright (c) 2005 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   26  * POSSIBILITY OF SUCH DAMAGE.
   27  */
   28 
   29 /*
   30  * FreeBSD compatibility module. Try to deal with various FreeBSD sysctl calls.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __KERNEL_RCSID(0, "$NetBSD: freebsd_sysctl.c,v 1.14 2008/04/28 20:23:41 martin Exp $");
   35 
   36 #include <sys/param.h>
   37 #include <sys/systm.h>
   38 #include <sys/proc.h>
   39 #include <sys/mount.h>
   40 #include <sys/signal.h>
   41 #include <sys/signalvar.h>
   42 #include <sys/malloc.h>
   43 #include <sys/mman.h>
   44 #include <sys/sysctl.h>
   45 #include <sys/ktrace.h>
   46 
   47 #include <sys/syscallargs.h>
   48 
   49 #include <compat/freebsd/freebsd_syscallargs.h>
   50 #include <compat/common/compat_util.h>
   51 #include <compat/freebsd/freebsd_rtprio.h>
   52 #include <compat/freebsd/freebsd_timex.h>
   53 #include <compat/freebsd/freebsd_signal.h>
   54 #include <compat/freebsd/freebsd_mman.h>
   55 
   56 static int freebsd_sysctl_name2oid(char *, int *, int *);
   57 
   58 SYSCTL_SETUP_PROTO(freebsd_sysctl_setup);
   59 SYSCTL_SETUP(freebsd_sysctl_setup, "freebsd emulated sysctl setup")
   60 {
   61         sysctl_createv(clog, 0, NULL, NULL,
   62                         CTLFLAG_PERMANENT,
   63                         CTLTYPE_NODE, "kern", NULL,
   64                         NULL, 0, NULL, 0,
   65                         CTL_KERN, CTL_EOL);
   66         sysctl_createv(clog, 0, NULL, NULL,
   67                         CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
   68                         CTLTYPE_INT, "osreldate",
   69                         SYSCTL_DESCR("Operating system revision"),
   70                         NULL, __NetBSD_Version__, NULL, 0,
   71                         CTL_KERN, CTL_CREATE, CTL_EOL);
   72 }
   73 
   74 int
   75 freebsd_sys_sysctl(struct lwp *l, const struct freebsd_sys_sysctl_args *uap, register_t *retval)
   76 {
   77         /* {
   78                 syscallarg(int *) name;
   79                 syscallarg(u_int) namelen;
   80                 syscallarg(void *) old;
   81                 syscallarg(size_t *) oldlenp;
   82                 syscallarg(void *) new;
   83                 syscallarg(size_t) newlen;
   84         } */
   85         int error;
   86         int name[CTL_MAXNAME];
   87         size_t newlen, *oldlenp;
   88         u_int namelen;
   89         void *new, *old;
   90 
   91         namelen = SCARG(uap, namelen);
   92 
   93         if ((namelen > CTL_MAXNAME) || (namelen < 1))
   94                 return EINVAL;
   95 
   96         if ((error = copyin(SCARG(uap, name), name, 
   97             namelen * sizeof(*name))) != 0)
   98                 return error;
   99 
  100         if (namelen > 0 && name[0] != 0)
  101                 return(sys___sysctl(l, (const void *)uap, retval));
  102 
  103         ktrmib(name, namelen);
  104 
  105         /*
  106          * FreeBSD sysctl uses an undocumented set of special OIDs in it's
  107          * sysctl MIB whose tree is rooted at oid 0.  These OIDs are
  108          * interpretted by their sysctl to implement functions that NetBSD
  109          * performs in libc, such as sysctlgetmibinfo.
  110          *
  111          * From the FreeBSD kern_sysctl.c, these OIDs are:
  112          * {0,0}        printf the entire MIB-tree.
  113          * {0,1,...}    return the name of the "..." OID.
  114          * {0,2,...}    return the next OID.
  115          * {0,3}        return the OID of the name in "new"
  116          * {0,4,...}    return the kind & format info for the "..." OID.
  117          * {0,5,...}    return the description the "..." OID.
  118          *
  119          * Only implement {0,3} for now.
  120          */
  121 
  122         if (namelen < 2 || namelen > CTL_MAXNAME)
  123                 return(EINVAL);
  124 
  125         if (name[1] == 3) {
  126                 char *locnew;
  127                 int oid[CTL_MAXNAME];
  128                 u_int oidlen = CTL_MAXNAME;
  129 
  130                 new = SCARG(uap, new);
  131                 newlen = SCARG(uap, newlen);
  132                 if (new == NULL || newlen < 1 ||
  133                     newlen > (SYSCTL_NAMELEN * CTL_MAXNAME))
  134                         return(EINVAL);
  135 
  136                 old = SCARG(uap, old);
  137                 oldlenp = SCARG(uap, oldlenp);
  138                 if (old == NULL || oldlenp == NULL || *oldlenp < sizeof(int))
  139                         return(EINVAL);
  140 
  141                 if ((locnew =
  142                      (char *) malloc(newlen + 1, M_TEMP, M_WAITOK)) == NULL)
  143                         return(ENOMEM);
  144 
  145                 if ((error = copyinstr(new, locnew, newlen + 1, NULL))) {
  146                         free(locnew, M_TEMP);
  147                         return(error);
  148                 }
  149 
  150                 ktrmibio(-1, UIO_WRITE, new, newlen + 1, error);
  151                 sysctl_lock(new != NULL);
  152                 error = freebsd_sysctl_name2oid(locnew, oid, &oidlen);
  153                 sysctl_unlock();
  154                 free(locnew, M_TEMP);
  155                 if (error)
  156                         return(error);
  157 
  158                 oidlen *= sizeof(int);
  159                 error = copyout(oid, SCARG(uap, old),
  160                                 MIN(oidlen, *SCARG(uap, oldlenp)));
  161                 if (error)
  162                         return(error);
  163                 ktrmibio(-1, UIO_READ, SCARG(uap, old),
  164                     MIN(oidlen, *SCARG(uap, oldlenp)),  0);
  165 
  166                 error = copyout(&oidlen, SCARG(uap, oldlenp), sizeof(u_int));
  167 
  168                 return(error);
  169         }
  170 
  171         return(EOPNOTSUPP);
  172 }
  173 
  174 static int
  175 freebsd_sysctl_name2oid(char *name, int *oid, int *oidlen)
  176 {
  177         char *dot;
  178         int oi, ci;
  179         struct sysctlnode *node, *pnode;
  180 
  181         pnode = &sysctl_root;
  182         node = sysctl_root.sysctl_child;
  183         oi = 0;
  184         if ((dot = strchr(name, (int)'.')) != NULL)
  185                 *dot++ = '\0';
  186 
  187 next:
  188         while (*name != '\0' && node != NULL) {
  189                 for (ci = 0; ci < pnode->sysctl_clen; ci++) {
  190                         if (strcmp(name, node[ci].sysctl_name) == 0) {
  191                                 oid[oi++] = node[ci].sysctl_num;
  192                                 if ((name = dot) == NULL) {
  193                                         *oidlen = oi;
  194                                         return(0);
  195                                 }
  196                                 if ((dot = strchr(name, (int)'.')) != NULL)
  197                                         *dot++ = '\0';
  198 
  199                                 if (SYSCTL_TYPE(node[ci].sysctl_flags) !=
  200                                     CTLTYPE_NODE)
  201                                         return(ENOTDIR);
  202 
  203                                 pnode = &node[ci];
  204                                 node = pnode->sysctl_child;
  205                                 goto next;
  206                         }
  207                 }
  208 
  209                 /* no more nodes, it must not exist */
  210                 break;
  211         }
  212 
  213         return(ENOENT);
  214 }

Cache object: 841964a16413d3dd633172c21ebc74a8


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.