diff --git a/proc/readproc.c b/proc/readproc.c index 1e9d3414..63dbd5c9 100644 --- a/proc/readproc.c +++ b/proc/readproc.c @@ -600,7 +600,7 @@ static char** file2strvec(const char* directory, const char* what) { // this is the former under utilized 'read_cmdline', which has been // generalized in support of these new libproc flags: - // PROC_EDITCGRPCVT, PROC_EDITCMDLCVT + // PROC_EDITCGRPCVT, PROC_EDITCMDLCVT and PROC_EDITENVRCVT static int read_unvectored(char *restrict const dst, unsigned sz, const char* whom, const char *what, char sep) { char path[PROCPATHLEN]; int fd; @@ -690,6 +690,17 @@ static void fill_cmdline_cvt (const char* directory, proc_t *restrict p) { #undef uFLG } + // This routine reads an 'environ' for the designated proc_t and + // guarantees the caller a valid proc_t.environ pointer. +static void fill_environ_cvt (const char* directory, proc_t *restrict p) { + int whackable_int = MAX_BUFSZ; + + dst_buffer[0] = '\0'; + if (read_unvectored(src_buffer, MAX_BUFSZ, directory, "environ", ' ')) + escape_str(dst_buffer, src_buffer, MAX_BUFSZ, &whackable_int); + p->environ = vectorize_this_str(dst_buffer[0] ? dst_buffer : "-"); +} + // warning: interface may change int read_cmdline(char *restrict const dst, unsigned sz, unsigned pid) { char path[PROCPATHLEN]; @@ -781,9 +792,12 @@ static proc_t* simple_readproc(PROCTAB *restrict const PT, proc_t *restrict cons } } - if (unlikely(flags & PROC_FILLENV)) // read /proc/#/environ - p->environ = file2strvec(path, "environ"); - else + if (unlikely(flags & PROC_FILLENV)) { // read /proc/#/environ + if (flags & PROC_EDITENVRCVT) + fill_environ_cvt(path, p); + else + p->environ = file2strvec(path, "environ"); + } else p->environ = NULL; if (flags & (PROC_FILLCOM|PROC_FILLARG)) { // read /proc/#/cmdline @@ -890,9 +904,12 @@ static proc_t* simple_readtask(PROCTAB *restrict const PT, const proc_t *restric if (flags & PROC_FILLSUPGRP) supgrps_from_supgids(t); #endif - if (unlikely(flags & PROC_FILLENV)) // read /proc/#/task/#/environ - t->environ = file2strvec(path, "environ"); - else + if (unlikely(flags & PROC_FILLENV)) { // read /proc/#/task/#/environ + if (flags & PROC_EDITENVRCVT) + fill_environ_cvt(path, t); + else + t->environ = file2strvec(path, "environ"); + } else t->environ = NULL; if (flags & (PROC_FILLCOM|PROC_FILLARG)) { // read /proc/#/task/#/cmdline diff --git a/proc/readproc.h b/proc/readproc.h index 2bfbfb08..774fd3bc 100644 --- a/proc/readproc.h +++ b/proc/readproc.h @@ -272,6 +272,7 @@ extern proc_t * get_proc_stats(pid_t pid, proc_t *p); #define PROC_EDITCGRPCVT 0x10000 // edit `cgroup' as single vector #define PROC_EDITCMDLCVT 0x20000 // edit `cmdline' as single vector +#define PROC_EDITENVRCVT 0x40000 // edit `environ' as single vector // it helps to give app code a few spare bits #define PROC_SPARE_1 0x01000000