Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_sysctl.c
Show First 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | |||||
#include <net/vnet.h> | #include <net/vnet.h> | ||||
#include <security/mac/mac_framework.h> | #include <security/mac/mac_framework.h> | ||||
#include <vm/vm.h> | #include <vm/vm.h> | ||||
#include <vm/vm_extern.h> | #include <vm/vm_extern.h> | ||||
static MALLOC_DEFINE(M_SYSCTL, "sysctl", "sysctl internal magic"); | /* Can't be static, used by freebsd32 compat. */ | ||||
MALLOC_DEFINE(M_SYSCTL, "sysctl", "sysctl internal magic"); | |||||
static MALLOC_DEFINE(M_SYSCTLOID, "sysctloid", "sysctl dynamic oids"); | static MALLOC_DEFINE(M_SYSCTLOID, "sysctloid", "sysctl dynamic oids"); | ||||
static MALLOC_DEFINE(M_SYSCTLTMP, "sysctltmp", "sysctl temp output buffer"); | static MALLOC_DEFINE(M_SYSCTLTMP, "sysctltmp", "sysctl temp output buffer"); | ||||
/* | /* | ||||
* The sysctllock protects the MIB tree. It also protects sysctl | * The sysctllock protects the MIB tree. It also protects sysctl | ||||
* contexts used with dynamic sysctls. The sysctl_register_oid() and | * contexts used with dynamic sysctls. The sysctl_register_oid() and | ||||
* sysctl_unregister_oid() routines require the sysctllock to already | * sysctl_unregister_oid() routines require the sysctllock to already | ||||
* be held, so the sysctl_wlock() and sysctl_wunlock() routines are | * be held, so the sysctl_wlock() and sysctl_wunlock() routines are | ||||
▲ Show 20 Lines • Show All 1,981 Lines • ▼ Show 20 Lines | sys___sysctl(struct thread *td, struct sysctl_args *uap) | ||||
if (error && error != ENOMEM) | if (error && error != ENOMEM) | ||||
return (error); | return (error); | ||||
if (uap->oldlenp) { | if (uap->oldlenp) { | ||||
i = copyout(&j, uap->oldlenp, sizeof(j)); | i = copyout(&j, uap->oldlenp, sizeof(j)); | ||||
if (i) | if (i) | ||||
return (i); | return (i); | ||||
} | } | ||||
return (error); | return (error); | ||||
} | |||||
#ifndef _SYS_SYSPROTO_H_ | |||||
struct sysctlbyname_args { | |||||
const char *name; | |||||
u_int namelen; | |||||
void *old; | |||||
size_t *oldlenp; | |||||
void *new; | |||||
size_t newlen; | |||||
}; | |||||
#endif | |||||
int | |||||
sys___sysctlbyname(struct thread *td, struct sysctlbyname_args *uap) | |||||
{ | |||||
int oid[CTL_MAXNAME]; | |||||
#define NAMEBUFLEN 16 | |||||
char namebuf[NAMEBUFLEN]; | |||||
char *name; | |||||
size_t namelen, oidlen, rv; | |||||
int error; | |||||
namelen = uap->namelen; | |||||
if (namelen > MAXPATHLEN || namelen == 0) | |||||
return (EINVAL); | |||||
name = namebuf; | |||||
if (namelen > NAMEBUFLEN) | |||||
name = malloc(namelen, M_SYSCTL, M_WAITOK); | |||||
error = copyin(uap->name, name, namelen); | |||||
if (error) | |||||
goto out; | |||||
oid[0] = 0; | |||||
oid[1] = 3; | |||||
oidlen = sizeof(oid); | |||||
error = kernel_sysctl(td, oid, 2, oid, &oidlen, (void *)name, namelen, | |||||
&rv, 0); | |||||
if (error) | |||||
goto out; | |||||
error = userland_sysctl(td, oid, rv / sizeof(int), uap->old, uap->oldlenp, | |||||
0, (void *)uap->new, uap->newlen, &rv, 0); | |||||
if (error) | |||||
goto out; | |||||
if (uap->oldlenp) | |||||
error = copyout(&rv, uap->oldlenp, sizeof(rv)); | |||||
out: | |||||
if (namelen > NAMEBUFLEN) | |||||
free(name, M_SYSCTL); | |||||
return (error); | |||||
#undef NAMEBUFLEN | |||||
} | } | ||||
/* | /* | ||||
* This is used from various compatibility syscalls too. That's why name | * This is used from various compatibility syscalls too. That's why name | ||||
* must be in kernel space. | * must be in kernel space. | ||||
*/ | */ | ||||
int | int | ||||
userland_sysctl(struct thread *td, int *name, u_int namelen, void *old, | userland_sysctl(struct thread *td, int *name, u_int namelen, void *old, | ||||
▲ Show 20 Lines • Show All 98 Lines • Show Last 20 Lines |