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

📄 kern_sysctl.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	*oldlenp = sizeof(int);	if (oldp)		error = copyout((caddr_t)&val, oldp, sizeof(int));	return (error);}/* * Validate parameters and get old / set new parameters * for a string-valued sysctl function. */sysctl_string(oldp, oldlenp, newp, newlen, str, maxlen)	void *oldp;	size_t *oldlenp;	void *newp;	size_t newlen;	char *str;	int maxlen;{	int len, error = 0;	len = strlen(str) + 1;	if (oldp && *oldlenp < len)		return (ENOMEM);	if (newp && newlen >= maxlen)		return (EINVAL);	if (oldp) {		*oldlenp = len;		error = copyout(str, oldp, len);	}	if (error == 0 && newp) {		error = copyin(newp, str, newlen);		str[newlen] = 0;	}	return (error);}/* * As above, but read-only. */sysctl_rdstring(oldp, oldlenp, newp, str)	void *oldp;	size_t *oldlenp;	void *newp;	char *str;{	int len, error = 0;	len = strlen(str) + 1;	if (oldp && *oldlenp < len)		return (ENOMEM);	if (newp)		return (EPERM);	*oldlenp = len;	if (oldp)		error = copyout(str, oldp, len);	return (error);}/* * Validate parameters and get old / set new parameters * for a structure oriented sysctl function. */sysctl_struct(oldp, oldlenp, newp, newlen, sp, len)	void *oldp;	size_t *oldlenp;	void *newp;	size_t newlen;	void *sp;	int len;{	int error = 0;	if (oldp && *oldlenp < len)		return (ENOMEM);	if (newp && newlen > len)		return (EINVAL);	if (oldp) {		*oldlenp = len;		error = copyout(sp, oldp, len);	}	if (error == 0 && newp)		error = copyin(newp, sp, len);	return (error);}/* * Validate parameters and get old parameters * for a structure oriented sysctl function. */sysctl_rdstruct(oldp, oldlenp, newp, sp, len)	void *oldp;	size_t *oldlenp;	void *newp, *sp;	int len;{	int error = 0;	if (oldp && *oldlenp < len)		return (ENOMEM);	if (newp)		return (EPERM);	*oldlenp = len;	if (oldp)		error = copyout(sp, oldp, len);	return (error);}/* * Get file structures. */sysctl_file(where, sizep)	char *where;	size_t *sizep;{	int buflen, error;	struct file *fp;	char *start = where;	buflen = *sizep;	if (where == NULL) {		/*		 * overestimate by 10 files		 */		*sizep = sizeof(filehead) + (nfiles + 10) * sizeof(struct file);		return (0);	}	/*	 * first copyout filehead	 */	if (buflen < sizeof(filehead)) {		*sizep = 0;		return (0);	}	if (error = copyout((caddr_t)&filehead, where, sizeof(filehead)))		return (error);	buflen -= sizeof(filehead);	where += sizeof(filehead);	/*	 * followed by an array of file structures	 */	for (fp = filehead; fp != NULL; fp = fp->f_filef) {		if (buflen < sizeof(struct file)) {			*sizep = where - start;			return (ENOMEM);		}		if (error = copyout((caddr_t)fp, where, sizeof (struct file)))			return (error);		buflen -= sizeof(struct file);		where += sizeof(struct file);	}	*sizep = where - start;	return (0);}/* * try over estimating by 5 procs */#define KERN_PROCSLOP	(5 * sizeof (struct kinfo_proc))sysctl_doproc(name, namelen, where, sizep)	int *name;	u_int namelen;	char *where;	size_t *sizep;{	register struct proc *p;	register struct kinfo_proc *dp = (struct kinfo_proc *)where;	register int needed = 0;	int buflen = where != NULL ? *sizep : 0;	int doingzomb;	struct eproc eproc;	int error = 0;	if (namelen != 2 && !(namelen == 1 && name[0] == KERN_PROC_ALL))		return (EINVAL);	p = (struct proc *)allproc;	doingzomb = 0;again:	for (; p != NULL; p = p->p_next) {		/*		 * Skip embryonic processes.		 */		if (p->p_stat == SIDL)			continue;		/*		 * TODO - make more efficient (see notes below).		 * do by session.		 */		switch (name[0]) {		case KERN_PROC_PID:			/* could do this with just a lookup */			if (p->p_pid != (pid_t)name[1])				continue;			break;		case KERN_PROC_PGRP:			/* could do this by traversing pgrp */			if (p->p_pgrp->pg_id != (pid_t)name[1])				continue;			break;		case KERN_PROC_TTY:			if ((p->p_flag & P_CONTROLT) == 0 ||			    p->p_session->s_ttyp == NULL ||			    p->p_session->s_ttyp->t_dev != (dev_t)name[1])				continue;			break;		case KERN_PROC_UID:			if (p->p_ucred->cr_uid != (uid_t)name[1])				continue;			break;		case KERN_PROC_RUID:			if (p->p_cred->p_ruid != (uid_t)name[1])				continue;			break;		}		if (buflen >= sizeof(struct kinfo_proc)) {			fill_eproc(p, &eproc);			if (error = copyout((caddr_t)p, &dp->kp_proc,			    sizeof(struct proc)))				return (error);			if (error = copyout((caddr_t)&eproc, &dp->kp_eproc,			    sizeof(eproc)))				return (error);			dp++;			buflen -= sizeof(struct kinfo_proc);		}		needed += sizeof(struct kinfo_proc);	}	if (doingzomb == 0) {		p = zombproc;		doingzomb++;		goto again;	}	if (where != NULL) {		*sizep = (caddr_t)dp - where;		if (needed > *sizep)			return (ENOMEM);	} else {		needed += KERN_PROCSLOP;		*sizep = needed;	}	return (0);}/* * Fill in an eproc structure for the specified process. */voidfill_eproc(p, ep)	register struct proc *p;	register struct eproc *ep;{	register struct tty *tp;	ep->e_paddr = p;	ep->e_sess = p->p_pgrp->pg_session;	ep->e_pcred = *p->p_cred;	ep->e_ucred = *p->p_ucred;	if (p->p_stat == SIDL || p->p_stat == SZOMB) {		ep->e_vm.vm_rssize = 0;		ep->e_vm.vm_tsize = 0;		ep->e_vm.vm_dsize = 0;		ep->e_vm.vm_ssize = 0;#ifndef sparc		/* ep->e_vm.vm_pmap = XXX; */#endif	} else {		register struct vmspace *vm = p->p_vmspace;#ifdef pmap_resident_count		ep->e_vm.vm_rssize = pmap_resident_count(&vm->vm_pmap); /*XXX*/#else		ep->e_vm.vm_rssize = vm->vm_rssize;#endif		ep->e_vm.vm_tsize = vm->vm_tsize;		ep->e_vm.vm_dsize = vm->vm_dsize;		ep->e_vm.vm_ssize = vm->vm_ssize;#ifndef sparc		ep->e_vm.vm_pmap = vm->vm_pmap;#endif	}	if (p->p_pptr)		ep->e_ppid = p->p_pptr->p_pid;	else		ep->e_ppid = 0;	ep->e_pgid = p->p_pgrp->pg_id;	ep->e_jobc = p->p_pgrp->pg_jobc;	if ((p->p_flag & P_CONTROLT) &&	     (tp = ep->e_sess->s_ttyp)) {		ep->e_tdev = tp->t_dev;		ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;		ep->e_tsess = tp->t_session;	} else		ep->e_tdev = NODEV;	ep->e_flag = ep->e_sess->s_ttyvp ? EPROC_CTTY : 0;	if (SESS_LEADER(p))		ep->e_flag |= EPROC_SLEADER;	if (p->p_wmesg)		strncpy(ep->e_wmesg, p->p_wmesg, WMESGLEN);	ep->e_xsize = ep->e_xrssize = 0;	ep->e_xccount = ep->e_xswrss = 0;}#ifdef COMPAT_43#include <sys/socket.h>#define	KINFO_PROC		(0<<8)#define	KINFO_RT		(1<<8)#define	KINFO_VNODE		(2<<8)#define	KINFO_FILE		(3<<8)#define	KINFO_METER		(4<<8)#define	KINFO_LOADAVG		(5<<8)#define	KINFO_CLOCKRATE		(6<<8)struct getkerninfo_args {	int	op;	char	*where;	int	*size;	int	arg;};ogetkerninfo(p, uap, retval)	struct proc *p;	register struct getkerninfo_args *uap;	int *retval;{	int error, name[5];	u_int size;	if (uap->size &&	    (error = copyin((caddr_t)uap->size, (caddr_t)&size, sizeof(size))))		return (error);	switch (uap->op & 0xff00) {	case KINFO_RT:		name[0] = PF_ROUTE;		name[1] = 0;		name[2] = (uap->op & 0xff0000) >> 16;		name[3] = uap->op & 0xff;		name[4] = uap->arg;		error = net_sysctl(name, 5, uap->where, &size, NULL, 0, p);		break;	case KINFO_VNODE:		name[0] = KERN_VNODE;		error = kern_sysctl(name, 1, uap->where, &size, NULL, 0, p);		break;	case KINFO_PROC:		name[0] = KERN_PROC;		name[1] = uap->op & 0xff;		name[2] = uap->arg;		error = kern_sysctl(name, 3, uap->where, &size, NULL, 0, p);		break;	case KINFO_FILE:		name[0] = KERN_FILE;		error = kern_sysctl(name, 1, uap->where, &size, NULL, 0, p);		break;	case KINFO_METER:		name[0] = VM_METER;		error = vm_sysctl(name, 1, uap->where, &size, NULL, 0, p);		break;	case KINFO_LOADAVG:		name[0] = VM_LOADAVG;		error = vm_sysctl(name, 1, uap->where, &size, NULL, 0, p);		break;	case KINFO_CLOCKRATE:		name[0] = KERN_CLOCKRATE;		error = kern_sysctl(name, 1, uap->where, &size, NULL, 0, p);		break;	default:		return (EOPNOTSUPP);	}	if (error)		return (error);	*retval = size;	if (uap->size)		error = copyout((caddr_t)&size, (caddr_t)uap->size,		    sizeof(size));	return (error);}#endif /* COMPAT_43 */

⌨️ 快捷键说明

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