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 <james.warner@comcast.net>
This commit is contained in:
Jim Warner 2018-06-22 00:00:00 -05:00 committed by Craig Small
parent 9d59ddc466
commit ad4269f118
4 changed files with 34 additions and 7 deletions

View File

@ -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) },

View File

@ -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

View File

@ -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

View File

@ -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