From ad4269f1189d5a7d68765e291bcfa981b6731c25 Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Fri, 22 Jun 2018 00:00:00 -0500 Subject: [PATCH] library: expanded to provide for the 'executable path' This patch is the first of three implementing a newlib branch version of that Jan Rybar master merge request. With this series we'll ultimately extend 'EXE' support to both ps and top (plus, everyone else who wants it). Reference(s): . master branch merge request https://gitlab.com/procps-ng/procps/merge_requests/66 Signed-off-by: Jim Warner --- proc/pids.c | 3 +++ proc/pids.h | 1 + proc/readproc.c | 33 +++++++++++++++++++++++++++------ proc/readproc.h | 4 +++- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/proc/pids.c b/proc/pids.c index d3cc55d0..cfb2744e 100644 --- a/proc/pids.c +++ b/proc/pids.c @@ -155,6 +155,7 @@ STR_set(CMDLINE, cmdline) VEC_set(CMDLINE_V, cmdline_v) STR_set(ENVIRON, environ) VEC_set(ENVIRON_V, environ_v) +STR_set(EXE, exe) REG_set(EXIT_SIGNAL, s_int, exit_signal) REG_set(FLAGS, ul_int, flags) REG_set(FLT_MAJ, ul_int, maj_flt) @@ -343,6 +344,7 @@ srtDECL(noop) { // ___ Controlling Table |||||||||||||||||||||||||||||||||||||||||||||||||||||| #define f_either PROC_SPARE_1 // either status or stat (favor stat) +#define f_exe PROC_FILL_EXE #define f_grp PROC_FILLGRP #define f_login PROC_FILL_LUID #define f_lxc PROC_FILL_LXC @@ -406,6 +408,7 @@ static struct { { RS(CMDLINE_V), v_arg, FF(strv), QS(strv), 0, TS(strv) }, { RS(ENVIRON), x_environ, FF(str), QS(str), 0, TS(str) }, { RS(ENVIRON_V), v_env, FF(strv), QS(strv), 0, TS(strv) }, + { RS(EXE), f_exe, FF(str), QS(str), 0, TS(str) }, { RS(EXIT_SIGNAL), f_stat, NULL, QS(s_int), 0, TS(s_int) }, { RS(FLAGS), f_stat, NULL, QS(ul_int), 0, TS(ul_int) }, { RS(FLT_MAJ), f_stat, NULL, QS(ul_int), 0, TS(ul_int) }, diff --git a/proc/pids.h b/proc/pids.h index c183c88a..d1414efc 100644 --- a/proc/pids.h +++ b/proc/pids.h @@ -43,6 +43,7 @@ enum pids_item { PIDS_CMDLINE_V, // strv PIDS_ENVIRON, // str PIDS_ENVIRON_V, // strv + PIDS_EXE, // str PIDS_EXIT_SIGNAL, // s_int PIDS_FLAGS, // ul_int PIDS_FLT_MAJ, // ul_int diff --git a/proc/readproc.c b/proc/readproc.c index 0fc34cbe..0eaa5c78 100644 --- a/proc/readproc.c +++ b/proc/readproc.c @@ -90,16 +90,15 @@ static int task_dir_missing; // free any additional dynamically acquired storage associated with a proc_t // ( and if it's to be reused, refresh it otherwise destroy it ) static inline void free_acquired (proc_t *p, int reuse) { - if (p->environ) free((void*)p->environ); - if (p->cmdline) free((void*)p->cmdline); if (p->cgname) free((void*)p->cgname); if (p->cgroup) free((void*)p->cgroup); - if (p->environ_v) free((void*)*p->environ_v); - if (p->cmdline_v) free((void*)*p->cmdline_v); if (p->cgroup_v) free((void*)*p->cgroup_v); - if (p->supgid) free(p->supgid); - if (p->supgrp) free(p->supgrp); if (p->cmd) free(p->cmd); + if (p->cmdline) free((void*)p->cmdline); + if (p->cmdline_v) free((void*)*p->cmdline_v); + if (p->environ) free((void*)p->environ); + if (p->environ_v) free((void*)*p->environ_v); + if (p->exe) free(p->exe); if (p->sd_mach) free(p->sd_mach); if (p->sd_ouid) free(p->sd_ouid); if (p->sd_seat) free(p->sd_seat); @@ -107,6 +106,8 @@ static inline void free_acquired (proc_t *p, int reuse) { if (p->sd_slice) free(p->sd_slice); if (p->sd_unit) free(p->sd_unit); if (p->sd_uunit) free(p->sd_uunit); + if (p->supgid) free(p->supgid); + if (p->supgrp) free(p->supgrp); memset(p, reuse ? '\0' : '\xff', sizeof(*p)); } @@ -982,6 +983,20 @@ static int login_uid (const char *path) { } +static char *readlink_exe (const char *path){ + char buf[PROCPATHLEN]; + int in; + + snprintf(buf, sizeof(buf), "%s/exe", path); + in = (int)readlink(buf, dst_buffer, MAX_BUFSZ-1); + if (in > 0) { + dst_buffer[in] = '\0'; + return strdup(dst_buffer); + } + return strdup("-"); +} + + /////////////////////////////////////////////////////////////////////// /* These are some nice GNU C expression subscope "inline" functions. @@ -1106,6 +1121,9 @@ static proc_t* simple_readproc(PROCTAB *restrict const PT, proc_t *restrict cons if (flags & PROC_FILL_LUID) // value the login user id p->luid = login_uid(path); + if (flags & PROC_FILL_EXE) + p->exe = readlink_exe(path); + if (rc == 0) return p; errno = ENOMEM; next_proc: @@ -1193,6 +1211,9 @@ static proc_t* simple_readtask(PROCTAB *restrict const PT, const proc_t *restric if (flags & PROC_FILLSYSTEMD) // get sd-login.h stuff rc += sd2proc(t); + + if (flags & PROC_FILL_EXE) + t->exe = readlink_exe(path); #ifdef FALSE_THREADS } #endif diff --git a/proc/readproc.h b/proc/readproc.h index ec0acab3..d3d21ac9 100644 --- a/proc/readproc.h +++ b/proc/readproc.h @@ -162,7 +162,8 @@ typedef struct proc_t { *sd_unit, // n/a systemd system unit id *sd_uunit; // n/a systemd user unit id char - *lxcname; // n/a lxc container name + *lxcname, // n/a lxc container name + *exe; // exe executable path + name int luid; // loginuid user id at login } proc_t; @@ -224,6 +225,7 @@ typedef struct PROCTAB { #define PROC_FILLSYSTEMD 0x80000 // fill in proc_t systemd information #define PROC_FILL_LXC 0x800000 // fill in proc_t lxcname, if possible #define PROC_FILL_LUID 0x400000 // fill in proc_t luid (login user id) +#define PROC_FILL_EXE 0x200000 // fill in proc_t exe path + pgm name #define PROC_LOOSE_TASKS 0x2000 // treat threads as if they were processes