library: correct 'vectorized' string logic, <PIDS> api
The commit referenced below addressed (some) anomalies
surrounding 'strv' pointers. However, there remained a
couple quirks involving a potential NULL return value.
Any NULL values returned from the old library readproc
guys would cause no real harm for newlib. But they did
produce the misleading "[ duplicate ENUM_ID ]" result.
The following all represent potential NULL results and
suggest shortcomings in testing of that earlier patch.
. kernel threads do not have cgroup, cmdline & environ
. even if present environ could require root to access
So, this patch reverts a portion of the earlier commit
and ensures when some vectored string is not available
a traditional dash ('-') is the 'strv' returned value.
[ and we'll also correct one typo in the header file ]
Reference(s):
. eliminated a final potential NULL, <PIDS> api
commit 09503dc597
Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
parent
30e27d48e9
commit
a9bfb186eb
21
proc/pids.c
21
proc/pids.c
@ -94,25 +94,6 @@ struct pids_info {
|
||||
|
||||
// ___ Results 'Set' Support ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
|
||||
static char** pids_vectorize_this (const char* src) {
|
||||
#define pSZ (sizeof(char*))
|
||||
char *cpy, **vec;
|
||||
size_t adj, tot;
|
||||
|
||||
tot = strlen(src) + 1; // prep for our vectors
|
||||
if (tot < 1 || tot >= INT_MAX) tot = INT_MAX-1; // integer overflow?
|
||||
adj = (pSZ-1) - ((tot + pSZ-1) & (pSZ-1)); // calc alignment bytes
|
||||
cpy = calloc(1, tot + adj + (2 * pSZ)); // get new larger buffer
|
||||
if (!cpy) return NULL; // oops, looks like ENOMEM
|
||||
snprintf(cpy, tot, "%s", src); // duplicate their string
|
||||
vec = (char**)(cpy + tot + adj); // prep pointer to pointers
|
||||
*vec = cpy; // point 1st vector to string
|
||||
*(vec+1) = NULL; // null ptr 'list' delimit
|
||||
return vec; // ==> free(*vec) to dealloc
|
||||
#undef pSZ
|
||||
} // end: pids_vectorize_this
|
||||
|
||||
|
||||
#define setNAME(e) set_pids_ ## e
|
||||
#define setDECL(e) static void setNAME(e) \
|
||||
(struct pids_info *I, struct pids_result *R, proc_t *P)
|
||||
@ -136,7 +117,7 @@ static char** pids_vectorize_this (const char* src) {
|
||||
some sort of hint that they duplicated this char ** item ... */
|
||||
#define VEC_set(e,x) setDECL(e) { \
|
||||
if (NULL != P-> x) { R->result.strv = P-> x; P-> x = NULL; } \
|
||||
else { R->result.strv = pids_vectorize_this("[ duplicate " STRINGIFY(e) " ]"); \
|
||||
else { R->result.strv = vectorize_this_str("[ duplicate " STRINGIFY(e) " ]"); \
|
||||
if (!R->result.str) I->seterr = 1; } }
|
||||
|
||||
|
||||
|
@ -132,7 +132,7 @@ enum pids_item {
|
||||
PIDS_TICS_USER, // ull_int stat: utime
|
||||
PIDS_TICS_USER_C, // ull_int stat: utime + cutime
|
||||
PIDS_TIME_ALL, // ull_int [ derived from (utime + stime) / hertz ]
|
||||
PIDS_TIME_ELAPSED, // ull_int [ derived from /proc/uptime - (starttime / hertz) }
|
||||
PIDS_TIME_ELAPSED, // ull_int [ derived from /proc/uptime - (starttime / hertz) ]
|
||||
PIDS_TIME_START, // ull_int stat: starttime
|
||||
PIDS_TTY, // s_int stat: tty_nr
|
||||
PIDS_TTY_NAME, // str [ derived from TTY ]
|
||||
|
@ -835,6 +835,34 @@ static int read_unvectored(char *restrict const dst, unsigned sz, const char* wh
|
||||
}
|
||||
|
||||
|
||||
char** vectorize_this_str (const char* src) {
|
||||
#define pSZ (sizeof(char*))
|
||||
char *cpy, **vec;
|
||||
size_t adj, tot;
|
||||
|
||||
tot = strlen(src) + 1; // prep for our vectors
|
||||
if (tot < 1 || tot >= INT_MAX) tot = INT_MAX-1; // integer overflow?
|
||||
adj = (pSZ-1) - ((tot + pSZ-1) & (pSZ-1)); // calc alignment bytes
|
||||
cpy = calloc(1, tot + adj + (2 * pSZ)); // get new larger buffer
|
||||
if (!cpy) return NULL; // oops, looks like ENOMEM
|
||||
snprintf(cpy, tot, "%s", src); // duplicate their string
|
||||
vec = (char**)(cpy + tot + adj); // prep pointer to pointers
|
||||
*vec = cpy; // point 1st vector to string
|
||||
*(vec+1) = NULL; // null ptr 'list' delimit
|
||||
return vec; // ==> free(*vec) to dealloc
|
||||
#undef pSZ
|
||||
}
|
||||
|
||||
|
||||
// This littl' guy just serves those true vectorized fields
|
||||
// ( when a /proc source field didn't exist )
|
||||
static int vectorize_dash_rc (char*** vec) {
|
||||
if (!(*vec = vectorize_this_str("-")))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// This routine reads a 'cgroup' for the designated proc_t and
|
||||
// guarantees the caller a valid proc_t.cgroup pointer.
|
||||
static int fill_cgroup_cvt (const char* directory, proc_t *restrict p) {
|
||||
@ -1094,17 +1122,20 @@ static proc_t* simple_readproc(PROCTAB *restrict const PT, proc_t *restrict cons
|
||||
}
|
||||
|
||||
if (flags & PROC_FILLENV) // read /proc/#/environ
|
||||
p->environ_v = file2strvec(path, "environ");
|
||||
if (!(p->environ_v = file2strvec(path, "environ")))
|
||||
rc += vectorize_dash_rc(&p->environ_v);
|
||||
if (flags & PROC_EDITENVRCVT)
|
||||
rc += fill_environ_cvt(path, p);
|
||||
|
||||
if (flags & PROC_FILLARG) // read /proc/#/cmdline
|
||||
p->cmdline_v = file2strvec(path, "cmdline");
|
||||
if (!(p->cmdline_v = file2strvec(path, "cmdline")))
|
||||
rc += vectorize_dash_rc(&p->cmdline_v);
|
||||
if (flags & PROC_EDITCMDLCVT)
|
||||
rc += fill_cmdline_cvt(path, p);
|
||||
|
||||
if ((flags & PROC_FILLCGROUP)) // read /proc/#/cgroup
|
||||
p->cgroup_v = file2strvec(path, "cgroup");
|
||||
if (!(p->cgroup_v = file2strvec(path, "cgroup")))
|
||||
rc += vectorize_dash_rc(&p->cgroup_v);
|
||||
if (flags & PROC_EDITCGRPCVT)
|
||||
rc += fill_cgroup_cvt(path, p);
|
||||
|
||||
@ -1202,17 +1233,20 @@ static proc_t* simple_readtask(PROCTAB *restrict const PT, const proc_t *restric
|
||||
if (!IS_THREAD(t)) {
|
||||
#endif
|
||||
if (flags & PROC_FILLARG) // read /proc/#/task/#/cmdline
|
||||
t->cmdline_v = file2strvec(path, "cmdline");
|
||||
if (!(t->cmdline_v = file2strvec(path, "cmdline")))
|
||||
rc += vectorize_dash_rc(&t->cmdline_v);
|
||||
if (flags & PROC_EDITCMDLCVT)
|
||||
rc += fill_cmdline_cvt(path, t);
|
||||
|
||||
if (flags & PROC_FILLENV) // read /proc/#/task/#/environ
|
||||
t->environ_v = file2strvec(path, "environ");
|
||||
if (!(t->environ_v = file2strvec(path, "environ")))
|
||||
rc += vectorize_dash_rc(&t->environ_v);
|
||||
if (flags & PROC_EDITENVRCVT)
|
||||
rc += fill_environ_cvt(path, t);
|
||||
|
||||
if ((flags & PROC_FILLCGROUP)) // read /proc/#/task/#/cgroup
|
||||
t->cgroup_v = file2strvec(path, "cgroup");
|
||||
if (!(t->cgroup_v = file2strvec(path, "cgroup")))
|
||||
rc += vectorize_dash_rc(&t->cgroup_v);
|
||||
if (flags & PROC_EDITCGRPCVT)
|
||||
rc += fill_cgroup_cvt(path, t);
|
||||
|
||||
|
@ -260,5 +260,6 @@ proc_t* readproc(PROCTAB *__restrict const PT, proc_t *__restrict p);
|
||||
proc_t* readeither(PROCTAB *__restrict const PT, proc_t *__restrict x);
|
||||
int look_up_our_self(proc_t *p);
|
||||
void closeproc(PROCTAB* PT);
|
||||
char** vectorize_this_str(const char* src);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user