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 ||||||||||||||||||||||||||||||||||||||||||||||||||
|
// ___ 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 setNAME(e) set_pids_ ## e
|
||||||
#define setDECL(e) static void setNAME(e) \
|
#define setDECL(e) static void setNAME(e) \
|
||||||
(struct pids_info *I, struct pids_result *R, proc_t *P)
|
(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 ... */
|
some sort of hint that they duplicated this char ** item ... */
|
||||||
#define VEC_set(e,x) setDECL(e) { \
|
#define VEC_set(e,x) setDECL(e) { \
|
||||||
if (NULL != P-> x) { R->result.strv = P-> x; P-> x = NULL; } \
|
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; } }
|
if (!R->result.str) I->seterr = 1; } }
|
||||||
|
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ enum pids_item {
|
|||||||
PIDS_TICS_USER, // ull_int stat: utime
|
PIDS_TICS_USER, // ull_int stat: utime
|
||||||
PIDS_TICS_USER_C, // ull_int stat: utime + cutime
|
PIDS_TICS_USER_C, // ull_int stat: utime + cutime
|
||||||
PIDS_TIME_ALL, // ull_int [ derived from (utime + stime) / hertz ]
|
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_TIME_START, // ull_int stat: starttime
|
||||||
PIDS_TTY, // s_int stat: tty_nr
|
PIDS_TTY, // s_int stat: tty_nr
|
||||||
PIDS_TTY_NAME, // str [ derived from TTY ]
|
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
|
// This routine reads a 'cgroup' for the designated proc_t and
|
||||||
// guarantees the caller a valid proc_t.cgroup pointer.
|
// guarantees the caller a valid proc_t.cgroup pointer.
|
||||||
static int fill_cgroup_cvt (const char* directory, proc_t *restrict p) {
|
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
|
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)
|
if (flags & PROC_EDITENVRCVT)
|
||||||
rc += fill_environ_cvt(path, p);
|
rc += fill_environ_cvt(path, p);
|
||||||
|
|
||||||
if (flags & PROC_FILLARG) // read /proc/#/cmdline
|
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)
|
if (flags & PROC_EDITCMDLCVT)
|
||||||
rc += fill_cmdline_cvt(path, p);
|
rc += fill_cmdline_cvt(path, p);
|
||||||
|
|
||||||
if ((flags & PROC_FILLCGROUP)) // read /proc/#/cgroup
|
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)
|
if (flags & PROC_EDITCGRPCVT)
|
||||||
rc += fill_cgroup_cvt(path, p);
|
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)) {
|
if (!IS_THREAD(t)) {
|
||||||
#endif
|
#endif
|
||||||
if (flags & PROC_FILLARG) // read /proc/#/task/#/cmdline
|
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)
|
if (flags & PROC_EDITCMDLCVT)
|
||||||
rc += fill_cmdline_cvt(path, t);
|
rc += fill_cmdline_cvt(path, t);
|
||||||
|
|
||||||
if (flags & PROC_FILLENV) // read /proc/#/task/#/environ
|
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)
|
if (flags & PROC_EDITENVRCVT)
|
||||||
rc += fill_environ_cvt(path, t);
|
rc += fill_environ_cvt(path, t);
|
||||||
|
|
||||||
if ((flags & PROC_FILLCGROUP)) // read /proc/#/task/#/cgroup
|
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)
|
if (flags & PROC_EDITCGRPCVT)
|
||||||
rc += fill_cgroup_cvt(path, t);
|
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);
|
proc_t* readeither(PROCTAB *__restrict const PT, proc_t *__restrict x);
|
||||||
int look_up_our_self(proc_t *p);
|
int look_up_our_self(proc_t *p);
|
||||||
void closeproc(PROCTAB* PT);
|
void closeproc(PROCTAB* PT);
|
||||||
|
char** vectorize_this_str(const char* src);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user