svn commit: r233926 - in stable/8/sys: kern sys
Mikolaj Golub
trociny at FreeBSD.org
Thu Apr 5 18:43:28 UTC 2012
Author: trociny
Date: Thu Apr 5 18:43:27 2012
New Revision: 233926
URL: http://svn.freebsd.org/changeset/base/233926
Log:
MFC r228648:
On start most of sysctl_kern_proc functions use the same pattern:
locate a process calling pfind() and do some additional checks like
p_candebug(). To reduce this code duplication a new function pget() is
introduced and used.
As the function may be useful not only in kern_proc.c it is in the
kernel name space.
Suggested by: kib
Reviewed by: kib
Modified:
stable/8/sys/kern/kern_proc.c
stable/8/sys/sys/proc.h
Directory Properties:
stable/8/sys/ (props changed)
Modified: stable/8/sys/kern/kern_proc.c
==============================================================================
--- stable/8/sys/kern/kern_proc.c Thu Apr 5 17:13:14 2012 (r233925)
+++ stable/8/sys/kern/kern_proc.c Thu Apr 5 18:43:27 2012 (r233926)
@@ -323,6 +323,55 @@ pgfind(pgid)
}
/*
+ * Locate process and do additional manipulations, depending on flags.
+ */
+int
+pget(pid_t pid, int flags, struct proc **pp)
+{
+ struct proc *p;
+ int error;
+
+ p = pfind(pid);
+ if (p == NULL)
+ return (ESRCH);
+ if ((flags & PGET_CANSEE) != 0) {
+ error = p_cansee(curthread, p);
+ if (error != 0)
+ goto errout;
+ }
+ if ((flags & PGET_CANDEBUG) != 0) {
+ error = p_candebug(curthread, p);
+ if (error != 0)
+ goto errout;
+ }
+ if ((flags & PGET_ISCURRENT) != 0 && curproc != p) {
+ error = EPERM;
+ goto errout;
+ }
+ if ((flags & PGET_NOTWEXIT) != 0 && (p->p_flag & P_WEXIT) != 0) {
+ error = ESRCH;
+ goto errout;
+ }
+ if ((flags & PGET_NOTINEXEC) != 0 && (p->p_flag & P_INEXEC) != 0) {
+ /*
+ * XXXRW: Not clear ESRCH is the right error during proc
+ * execve().
+ */
+ error = ESRCH;
+ goto errout;
+ }
+ if ((flags & PGET_HOLD) != 0) {
+ _PHOLD(p);
+ PROC_UNLOCK(p);
+ }
+ *pp = p;
+ return (0);
+errout:
+ PROC_UNLOCK(p);
+ return (error);
+}
+
+/*
* Create a new process group.
* pgid must be equal to the pid of p.
* Begin a new session if required.
@@ -1163,13 +1212,9 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS)
error = sysctl_wire_old_buffer(req, 0);
if (error)
return (error);
- p = pfind((pid_t)name[0]);
- if (!p)
- return (ESRCH);
- if ((error = p_cansee(curthread, p))) {
- PROC_UNLOCK(p);
+ error = pget((pid_t)name[0], PGET_CANSEE, &p);
+ if (error != 0)
return (error);
- }
error = sysctl_out_proc(p, req, flags);
return (error);
}
@@ -1361,24 +1406,17 @@ sysctl_kern_proc_args(SYSCTL_HANDLER_ARG
u_int namelen = arg2;
struct pargs *newpa, *pa;
struct proc *p;
- int error = 0;
+ int flags, error = 0;
if (namelen != 1)
return (EINVAL);
- p = pfind((pid_t)name[0]);
- if (!p)
- return (ESRCH);
-
- if ((error = p_cansee(curthread, p)) != 0) {
- PROC_UNLOCK(p);
+ flags = PGET_CANSEE;
+ if (req->newptr != NULL)
+ flags |= PGET_ISCURRENT;
+ error = pget((pid_t)name[0], flags, &p);
+ if (error)
return (error);
- }
-
- if (req->newptr && curproc != p) {
- PROC_UNLOCK(p);
- return (EPERM);
- }
pa = p->p_args;
pargs_hold(pa);
@@ -1424,13 +1462,9 @@ sysctl_kern_proc_pathname(SYSCTL_HANDLER
if (*pidp == -1) { /* -1 means this process */
p = req->td->td_proc;
} else {
- p = pfind(*pidp);
- if (p == NULL)
- return (ESRCH);
- if ((error = p_cansee(curthread, p)) != 0) {
- PROC_UNLOCK(p);
+ error = pget(*pidp, PGET_CANSEE, &p);
+ if (error != 0)
return (error);
- }
}
vp = p->p_textvp;
@@ -1467,12 +1501,9 @@ sysctl_kern_proc_sv_name(SYSCTL_HANDLER_
return (EINVAL);
name = (int *)arg1;
- if ((p = pfind((pid_t)name[0])) == NULL)
- return (ESRCH);
- if ((error = p_cansee(curthread, p))) {
- PROC_UNLOCK(p);
+ error = pget((pid_t)name[0], PGET_CANSEE, &p);
+ if (error != 0)
return (error);
- }
sv_name = p->p_sysent->sv_name;
PROC_UNLOCK(p);
return (sysctl_handle_string(oidp, sv_name, 0, req));
@@ -1499,18 +1530,9 @@ sysctl_kern_proc_ovmmap(SYSCTL_HANDLER_A
struct vmspace *vm;
name = (int *)arg1;
- if ((p = pfind((pid_t)name[0])) == NULL)
- return (ESRCH);
- if (p->p_flag & P_WEXIT) {
- PROC_UNLOCK(p);
- return (ESRCH);
- }
- if ((error = p_candebug(curthread, p))) {
- PROC_UNLOCK(p);
+ error = pget((pid_t)name[0], PGET_WANTREAD, &p);
+ if (error != 0)
return (error);
- }
- _PHOLD(p);
- PROC_UNLOCK(p);
vm = vmspace_acquire_ref(p);
if (vm == NULL) {
PRELE(p);
@@ -1677,18 +1699,9 @@ sysctl_kern_proc_vmmap(SYSCTL_HANDLER_AR
vm_map_t map;
name = (int *)arg1;
- if ((p = pfind((pid_t)name[0])) == NULL)
- return (ESRCH);
- if (p->p_flag & P_WEXIT) {
- PROC_UNLOCK(p);
- return (ESRCH);
- }
- if ((error = p_candebug(curthread, p))) {
- PROC_UNLOCK(p);
+ error = pget((pid_t)name[0], PGET_WANTREAD, &p);
+ if (error != 0)
return (error);
- }
- _PHOLD(p);
- PROC_UNLOCK(p);
vm = vmspace_acquire_ref(p);
if (vm == NULL) {
PRELE(p);
@@ -1851,19 +1864,9 @@ sysctl_kern_proc_kstack(SYSCTL_HANDLER_A
struct proc *p;
name = (int *)arg1;
- if ((p = pfind((pid_t)name[0])) == NULL)
- return (ESRCH);
- /* XXXRW: Not clear ESRCH is the right error during proc execve(). */
- if (p->p_flag & P_WEXIT || p->p_flag & P_INEXEC) {
- PROC_UNLOCK(p);
- return (ESRCH);
- }
- if ((error = p_candebug(curthread, p))) {
- PROC_UNLOCK(p);
+ error = pget((pid_t)name[0], PGET_NOTINEXEC | PGET_WANTREAD, &p);
+ if (error != 0)
return (error);
- }
- _PHOLD(p);
- PROC_UNLOCK(p);
kkstp = malloc(sizeof(*kkstp), M_TEMP, M_WAITOK);
st = stack_create();
@@ -1958,13 +1961,9 @@ sysctl_kern_proc_groups(SYSCTL_HANDLER_A
if (*pidp == -1) { /* -1 means this process */
p = req->td->td_proc;
} else {
- p = pfind(*pidp);
- if (p == NULL)
- return (ESRCH);
- if ((error = p_cansee(curthread, p)) != 0) {
- PROC_UNLOCK(p);
+ error = pget(*pidp, PGET_CANSEE, &p);
+ if (error != 0)
return (error);
- }
}
cred = crhold(p->p_ucred);
Modified: stable/8/sys/sys/proc.h
==============================================================================
--- stable/8/sys/sys/proc.h Thu Apr 5 17:13:14 2012 (r233925)
+++ stable/8/sys/sys/proc.h Thu Apr 5 18:43:27 2012 (r233926)
@@ -806,6 +806,20 @@ struct proc *pfind(pid_t); /* Find proc
struct pgrp *pgfind(pid_t); /* Find process group by id. */
struct proc *zpfind(pid_t); /* Find zombie process by id. */
+/*
+ * pget() flags.
+ */
+#define PGET_HOLD 0x00001 /* Hold the process. */
+#define PGET_CANSEE 0x00002 /* Check against p_cansee(). */
+#define PGET_CANDEBUG 0x00004 /* Check against p_candebug(). */
+#define PGET_ISCURRENT 0x00008 /* Check that the found process is current. */
+#define PGET_NOTWEXIT 0x00010 /* Check that the process is not in P_WEXIT. */
+#define PGET_NOTINEXEC 0x00020 /* Check that the process is not in P_INEXEC. */
+
+#define PGET_WANTREAD (PGET_HOLD | PGET_CANDEBUG | PGET_NOTWEXIT)
+
+int pget(pid_t pid, int flags, struct proc **pp);
+
void ast(struct trapframe *framep);
struct thread *choosethread(void);
int cr_cansignal(struct ucred *cred, struct proc *proc, int signum);
More information about the svn-src-stable-8
mailing list