⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kern_sysctl.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * Copyright (c) 1982, 1986, 1989, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * Mike Karels at Berkeley Software Design, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)kern_sysctl.c	8.4 (Berkeley) 4/14/94 *//* * sysctl system call. */#include <sys/param.h>#include <sys/systm.h>#include <sys/kernel.h>#include <sys/malloc.h>#include <sys/proc.h>#include <sys/file.h>#include <sys/vnode.h>#include <sys/unistd.h>#include <sys/buf.h>#include <sys/ioctl.h>#include <sys/tty.h>#include <vm/vm.h>#include <sys/sysctl.h>sysctlfn kern_sysctl;sysctlfn hw_sysctl;#ifdef DEBUGsysctlfn debug_sysctl;#endifextern sysctlfn vm_sysctl;extern sysctlfn fs_sysctl;extern sysctlfn net_sysctl;extern sysctlfn cpu_sysctl;/* * Locking and stats */static struct sysctl_lock {	int	sl_lock;	int	sl_want;	int	sl_locked;} memlock;struct sysctl_args {	int	*name;	u_int	namelen;	void	*old;	size_t	*oldlenp;	void	*new;	size_t	newlen;};int__sysctl(p, uap, retval)	struct proc *p;	register struct sysctl_args *uap;	int *retval;{	int error, dolock = 1;	u_int savelen, oldlen = 0;	sysctlfn *fn;	int name[CTL_MAXNAME];	if (uap->new != NULL && (error = suser(p->p_ucred, &p->p_acflag)))		return (error);	/*	 * all top-level sysctl names are non-terminal	 */	if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)		return (EINVAL);	if (error = copyin(uap->name, &name, uap->namelen * sizeof(int)))		return (error);	switch (name[0]) {	case CTL_KERN:		fn = kern_sysctl;		if (name[2] != KERN_VNODE)	/* XXX */			dolock = 0;		break;	case CTL_HW:		fn = hw_sysctl;		break;	case CTL_VM:		fn = vm_sysctl;		break;	case CTL_NET:		fn = net_sysctl;		break;#ifdef notyet	case CTL_FS:		fn = fs_sysctl;		break;#endif	case CTL_MACHDEP:		fn = cpu_sysctl;		break;#ifdef DEBUG	case CTL_DEBUG:		fn = debug_sysctl;		break;#endif	default:		return (EOPNOTSUPP);	}	if (uap->oldlenp &&	    (error = copyin(uap->oldlenp, &oldlen, sizeof(oldlen))))		return (error);	if (uap->old != NULL) {		if (!useracc(uap->old, oldlen, B_WRITE))			return (EFAULT);		while (memlock.sl_lock) {			memlock.sl_want = 1;			sleep((caddr_t)&memlock, PRIBIO+1);			memlock.sl_locked++;		}		memlock.sl_lock = 1;		if (dolock)			vslock(uap->old, oldlen);		savelen = oldlen;	}	error = (*fn)(name + 1, uap->namelen - 1, uap->old, &oldlen,	    uap->new, uap->newlen, p);	if (uap->old != NULL) {		if (dolock)			vsunlock(uap->old, savelen, B_WRITE);		memlock.sl_lock = 0;		if (memlock.sl_want) {			memlock.sl_want = 0;			wakeup((caddr_t)&memlock);		}	}	if (error)		return (error);	if (uap->oldlenp)		error = copyout(&oldlen, uap->oldlenp, sizeof(oldlen));	*retval = oldlen;	return (0);}/* * Attributes stored in the kernel. */char hostname[MAXHOSTNAMELEN];int hostnamelen;long hostid;int securelevel;/* * kernel related system variables. */kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)	int *name;	u_int namelen;	void *oldp;	size_t *oldlenp;	void *newp;	size_t newlen;	struct proc *p;{	int error, level, inthostid;	extern char ostype[], osrelease[], version[];	/* all sysctl names at this level are terminal */	if (namelen != 1 && !(name[0] == KERN_PROC || name[0] == KERN_PROF))		return (ENOTDIR);		/* overloaded */	switch (name[0]) {	case KERN_OSTYPE:		return (sysctl_rdstring(oldp, oldlenp, newp, ostype));	case KERN_OSRELEASE:		return (sysctl_rdstring(oldp, oldlenp, newp, osrelease));	case KERN_OSREV:		return (sysctl_rdint(oldp, oldlenp, newp, BSD));	case KERN_VERSION:		return (sysctl_rdstring(oldp, oldlenp, newp, version));	case KERN_MAXVNODES:		return(sysctl_int(oldp, oldlenp, newp, newlen, &desiredvnodes));	case KERN_MAXPROC:		return (sysctl_int(oldp, oldlenp, newp, newlen, &maxproc));	case KERN_MAXFILES:		return (sysctl_int(oldp, oldlenp, newp, newlen, &maxfiles));	case KERN_ARGMAX:		return (sysctl_rdint(oldp, oldlenp, newp, ARG_MAX));	case KERN_SECURELVL:		level = securelevel;		if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &level)) ||		    newp == NULL)			return (error);		if (level < securelevel && p->p_pid != 1)			return (EPERM);		securelevel = level;		return (0);	case KERN_HOSTNAME:		error = sysctl_string(oldp, oldlenp, newp, newlen,		    hostname, sizeof(hostname));		if (newp && !error)			hostnamelen = newlen;		return (error);	case KERN_HOSTID:		inthostid = hostid;  /* XXX assumes sizeof long <= sizeof int */		error =  sysctl_int(oldp, oldlenp, newp, newlen, &inthostid);		hostid = inthostid;		return (error);	case KERN_CLOCKRATE:		return (sysctl_clockrate(oldp, oldlenp));	case KERN_BOOTTIME:		return (sysctl_rdstruct(oldp, oldlenp, newp, &boottime,		    sizeof(struct timeval)));	case KERN_VNODE:		return (sysctl_vnode(oldp, oldlenp));	case KERN_PROC:		return (sysctl_doproc(name + 1, namelen - 1, oldp, oldlenp));	case KERN_FILE:		return (sysctl_file(oldp, oldlenp));#ifdef GPROF	case KERN_PROF:		return (sysctl_doprof(name + 1, namelen - 1, oldp, oldlenp,		    newp, newlen));#endif	case KERN_POSIX1:		return (sysctl_rdint(oldp, oldlenp, newp, _POSIX_VERSION));	case KERN_NGROUPS:		return (sysctl_rdint(oldp, oldlenp, newp, NGROUPS_MAX));	case KERN_JOB_CONTROL:		return (sysctl_rdint(oldp, oldlenp, newp, 1));	case KERN_SAVED_IDS:#ifdef _POSIX_SAVED_IDS		return (sysctl_rdint(oldp, oldlenp, newp, 1));#else		return (sysctl_rdint(oldp, oldlenp, newp, 0));#endif	default:		return (EOPNOTSUPP);	}	/* NOTREACHED */}/* * hardware related system variables. */hw_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)	int *name;	u_int namelen;	void *oldp;	size_t *oldlenp;	void *newp;	size_t newlen;	struct proc *p;{	extern char machine[], cpu_model[];	/* all sysctl names at this level are terminal */	if (namelen != 1)		return (ENOTDIR);		/* overloaded */	switch (name[0]) {	case HW_MACHINE:		return (sysctl_rdstring(oldp, oldlenp, newp, machine));	case HW_MODEL:		return (sysctl_rdstring(oldp, oldlenp, newp, cpu_model));	case HW_NCPU:		return (sysctl_rdint(oldp, oldlenp, newp, 1));	/* XXX */	case HW_BYTEORDER:		return (sysctl_rdint(oldp, oldlenp, newp, BYTE_ORDER));	case HW_PHYSMEM:		return (sysctl_rdint(oldp, oldlenp, newp, ctob(physmem)));	case HW_USERMEM:		return (sysctl_rdint(oldp, oldlenp, newp,		    ctob(physmem - cnt.v_wire_count)));	case HW_PAGESIZE:		return (sysctl_rdint(oldp, oldlenp, newp, PAGE_SIZE));	default:		return (EOPNOTSUPP);	}	/* NOTREACHED */}#ifdef DEBUG/* * Debugging related system variables. */struct ctldebug debug0, debug1, debug2, debug3, debug4;struct ctldebug debug5, debug6, debug7, debug8, debug9;struct ctldebug debug10, debug11, debug12, debug13, debug14;struct ctldebug debug15, debug16, debug17, debug18, debug19;static struct ctldebug *debugvars[CTL_DEBUG_MAXID] = {	&debug0, &debug1, &debug2, &debug3, &debug4,	&debug5, &debug6, &debug7, &debug8, &debug9,	&debug10, &debug11, &debug12, &debug13, &debug14,	&debug15, &debug16, &debug17, &debug18, &debug19,};intdebug_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)	int *name;	u_int namelen;	void *oldp;	size_t *oldlenp;	void *newp;	size_t newlen;	struct proc *p;{	struct ctldebug *cdp;	/* all sysctl names at this level are name and field */	if (namelen != 2)		return (ENOTDIR);		/* overloaded */	cdp = debugvars[name[0]];	if (cdp->debugname == 0)		return (EOPNOTSUPP);	switch (name[1]) {	case CTL_DEBUG_NAME:		return (sysctl_rdstring(oldp, oldlenp, newp, cdp->debugname));	case CTL_DEBUG_VALUE:		return (sysctl_int(oldp, oldlenp, newp, newlen, cdp->debugvar));	default:		return (EOPNOTSUPP);	}	/* NOTREACHED */}#endif /* DEBUG *//* * Validate parameters and get old / set new parameters * for an integer-valued sysctl function. */sysctl_int(oldp, oldlenp, newp, newlen, valp)	void *oldp;	size_t *oldlenp;	void *newp;	size_t newlen;	int *valp;{	int error = 0;	if (oldp && *oldlenp < sizeof(int))		return (ENOMEM);	if (newp && newlen != sizeof(int))		return (EINVAL);	*oldlenp = sizeof(int);	if (oldp)		error = copyout(valp, oldp, sizeof(int));	if (error == 0 && newp)		error = copyin(newp, valp, sizeof(int));	return (error);}/* * As above, but read-only. */sysctl_rdint(oldp, oldlenp, newp, val)	void *oldp;	size_t *oldlenp;	void *newp;	int val;{	int error = 0;	if (oldp && *oldlenp < sizeof(int))		return (ENOMEM);	if (newp)		return (EPERM);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -