summaryrefslogtreecommitdiffstats
path: root/lib/libprocstat
diff options
context:
space:
mode:
authortrociny <trociny@FreeBSD.org>2013-04-20 08:02:43 +0000
committertrociny <trociny@FreeBSD.org>2013-04-20 08:02:43 +0000
commit93aa05a11832f64ae31ddaef20437c6224698efc (patch)
tree0d441694eb852e9facccba792969dc68053737f8 /lib/libprocstat
parent16576036c320aca798d2600c23fd16c95b499140 (diff)
downloadFreeBSD-src-93aa05a11832f64ae31ddaef20437c6224698efc.zip
FreeBSD-src-93aa05a11832f64ae31ddaef20437c6224698efc.tar.gz
Add procstat_getpathname function to retrieve a process executable.
MFC after: 1 month
Diffstat (limited to 'lib/libprocstat')
-rw-r--r--lib/libprocstat/Symbol.map1
-rw-r--r--lib/libprocstat/libprocstat.320
-rw-r--r--lib/libprocstat/libprocstat.c65
-rw-r--r--lib/libprocstat/libprocstat.h6
4 files changed, 90 insertions, 2 deletions
diff --git a/lib/libprocstat/Symbol.map b/lib/libprocstat/Symbol.map
index 461d320..c4db0f3 100644
--- a/lib/libprocstat/Symbol.map
+++ b/lib/libprocstat/Symbol.map
@@ -20,6 +20,7 @@ FBSD_1.3 {
procstat_freevmmap;
procstat_get_shm_info;
procstat_getgroups;
+ procstat_getpathname;
procstat_getrlimit;
procstat_getumask;
procstat_getvmmap;
diff --git a/lib/libprocstat/libprocstat.3 b/lib/libprocstat/libprocstat.3
index bc78d68..fd843cb 100644
--- a/lib/libprocstat/libprocstat.3
+++ b/lib/libprocstat/libprocstat.3
@@ -34,6 +34,7 @@
.Nm procstat_close ,
.Nm procstat_getfiles ,
.Nm procstat_getgroups ,
+.Nm procstat_getpathname ,
.Nm procstat_getprocs ,
.Nm procstat_getumask ,
.Nm procstat_getvmmap ,
@@ -128,6 +129,13 @@
.Fa "unsigned int *count"
.Fc
.Ft "int"
+.Fo procstat_getpathname
+.Fa "struct procstat *procstat"
+.Fa "struct kinfo_proc *kp"
+.Fa "char *pathname"
+.Fa "size_t maxlen"
+.Fc
+.Ft "int"
.Fo procstat_getrlimit
.Fa "struct procstat *procstat"
.Fa "struct kinfo_proc *kp"
@@ -268,6 +276,18 @@ The caller is responsible to free the allocated memory with a subsequent
function call.
.Pp
The
+.Fn procstat_getpathname
+function gets a pointer to the
+.Vt procstat
+structure, a pointer to
+.Vt kinfo_proc
+structure, and copies the path of the process executable to
+.Fa pathname
+buffer, limiting to
+.Fa maxlen
+characters.
+.Pp
+The
.Fn procstat_getrlimit
function gets a pointer to the
.Vt procstat
diff --git a/lib/libprocstat/libprocstat.c b/lib/libprocstat/libprocstat.c
index 04c1058..e469f8e 100644
--- a/lib/libprocstat/libprocstat.c
+++ b/lib/libprocstat/libprocstat.c
@@ -136,6 +136,10 @@ static int procstat_get_vnode_info_sysctl(struct filestat *fst,
static gid_t *procstat_getgroups_core(struct procstat_core *core,
unsigned int *count);
static gid_t *procstat_getgroups_sysctl(pid_t pid, unsigned int *count);
+static int procstat_getpathname_core(struct procstat_core *core,
+ char *pathname, size_t maxlen);
+static int procstat_getpathname_sysctl(pid_t pid, char *pathname,
+ size_t maxlen);
static int procstat_getrlimit_core(struct procstat_core *core, int which,
struct rlimit* rlimit);
static int procstat_getrlimit_sysctl(pid_t pid, int which,
@@ -1780,3 +1784,64 @@ procstat_getrlimit(struct procstat *procstat, struct kinfo_proc *kp, int which,
return (-1);
}
}
+
+static int
+procstat_getpathname_sysctl(pid_t pid, char *pathname, size_t maxlen)
+{
+ int error, name[4];
+ size_t len;
+
+ name[0] = CTL_KERN;
+ name[1] = KERN_PROC;
+ name[2] = KERN_PROC_PATHNAME;
+ name[3] = pid;
+ len = maxlen;
+ error = sysctl(name, 4, pathname, &len, NULL, 0);
+ if (error != 0 && errno != ESRCH)
+ warn("sysctl: kern.proc.pathname: %d", pid);
+ if (len == 0)
+ pathname[0] = '\0';
+ return (error);
+}
+
+static int
+procstat_getpathname_core(struct procstat_core *core, char *pathname,
+ size_t maxlen)
+{
+ struct kinfo_file *files;
+ int cnt, i, result;
+
+ files = kinfo_getfile_core(core, &cnt);
+ if (files == NULL)
+ return (-1);
+ result = -1;
+ for (i = 0; i < cnt; i++) {
+ if (files[i].kf_fd != KF_FD_TYPE_TEXT)
+ continue;
+ strncpy(pathname, files[i].kf_path, maxlen);
+ result = 0;
+ break;
+ }
+ free(files);
+ return (result);
+}
+
+int
+procstat_getpathname(struct procstat *procstat, struct kinfo_proc *kp,
+ char *pathname, size_t maxlen)
+{
+ switch(procstat->type) {
+ case PROCSTAT_KVM:
+ warnx("kvm method is not supported");
+ return (-1);
+ case PROCSTAT_SYSCTL:
+ return (procstat_getpathname_sysctl(kp->ki_pid, pathname,
+ maxlen));
+ case PROCSTAT_CORE:
+ return (procstat_getpathname_core(procstat->core, pathname,
+ maxlen));
+ default:
+ warnx("unknown access method: %d", procstat->type);
+ return (-1);
+ }
+}
diff --git a/lib/libprocstat/libprocstat.h b/lib/libprocstat/libprocstat.h
index 05046af..24826ec 100644
--- a/lib/libprocstat/libprocstat.h
+++ b/lib/libprocstat/libprocstat.h
@@ -169,10 +169,12 @@ int procstat_get_vnode_info(struct procstat *procstat, struct filestat *fst,
struct vnstat *vn, char *errbuf);
gid_t *procstat_getgroups(struct procstat *procstat, struct kinfo_proc *kp,
unsigned int *count);
-int procstat_getumask(struct procstat *procstat, struct kinfo_proc *kp,
- unsigned short* umask);
+int procstat_getpathname(struct procstat *procstat, struct kinfo_proc *kp,
+ char *pathname, size_t maxlen);
int procstat_getrlimit(struct procstat *procstat, struct kinfo_proc *kp,
int which, struct rlimit* rlimit);
+int procstat_getumask(struct procstat *procstat, struct kinfo_proc *kp,
+ unsigned short* umask);
struct kinfo_vmentry *procstat_getvmmap(struct procstat *procstat,
struct kinfo_proc *kp, unsigned int *count);
struct procstat *procstat_open_core(const char *filename);
OpenPOWER on IntegriCloud