library: eliminate all dependencies on alloc.h/alloc.c
While that old master branch library may utilize those memory allocation functions found in the alloc module, it was inappropriate for this newlib branch to subject callers to a stderr message followed by an early exit. Of course, the old libprocps offered a message handler override provision (xalloc_err_handler) but that, too, would seem to be inappropriate for our modern library. [ remember the battles fought with that damn libnuma ] So, this commit will tweak those old inherited sources setting the stage for standardized return values/errno settings in connection with a memory allocation error. ------------------------------------------------------ Along the way, we'll address the following miscellany: . Completely eliminate usage of anything from alloc.h. This, of course, entails our own error checking of the alternative allocation calls from stdlib.h & string.h. . Eliminate use of the strdup function where possible, as with 'procps_uptime' and 'procps_loadavg' routines. . Whack some obsolete code (getslabinfo) in sysinfo.c. Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
parent
2d5b7e580f
commit
18e684d65d
@ -26,7 +26,6 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "devname.h"
|
#include "devname.h"
|
||||||
#include "alloc.h"
|
|
||||||
|
|
||||||
// This is the buffer size for a tty name. Any path is legal,
|
// This is the buffer size for a tty name. Any path is legal,
|
||||||
// which makes PAGE_SIZE appropriate (see kernel source), but
|
// which makes PAGE_SIZE appropriate (see kernel source), but
|
||||||
@ -83,7 +82,8 @@ static void load_drivers(void){
|
|||||||
end = strchr(p, ' ');
|
end = strchr(p, ' ');
|
||||||
if(!end) continue;
|
if(!end) continue;
|
||||||
len = end - p;
|
len = end - p;
|
||||||
tmn = xcalloc(sizeof(tty_map_node));
|
if (!(tmn = calloc(1, sizeof(tty_map_node))))
|
||||||
|
goto fail;
|
||||||
tmn->next = tty_map;
|
tmn->next = tty_map;
|
||||||
tty_map = tmn;
|
tty_map = tmn;
|
||||||
/* if we have a devfs type name such as /dev/tts/%d then strip the %d but
|
/* if we have a devfs type name such as /dev/tts/%d then strip the %d but
|
||||||
|
@ -28,14 +28,15 @@
|
|||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "pwcache.h"
|
#include "pwcache.h"
|
||||||
#include "procps-private.h"
|
#include "procps-private.h"
|
||||||
|
|
||||||
// might as well fill cache lines... else we waste memory anyway
|
// might as well fill cache lines... else we waste memory anyway
|
||||||
|
|
||||||
#define HASHSIZE 64 /* power of 2 */
|
#define HASHSIZE 64 /* power of 2 */
|
||||||
#define HASH(x) ((x) & (HASHSIZE - 1))
|
#define HASH(x) ((x) & (HASHSIZE - 1))
|
||||||
|
|
||||||
|
static char ERRname[] = "?";
|
||||||
|
|
||||||
static struct pwbuf {
|
static struct pwbuf {
|
||||||
struct pwbuf *next;
|
struct pwbuf *next;
|
||||||
@ -49,15 +50,16 @@ char *pwcache_get_user(uid_t uid) {
|
|||||||
|
|
||||||
p = &pwhash[HASH(uid)];
|
p = &pwhash[HASH(uid)];
|
||||||
while (*p) {
|
while (*p) {
|
||||||
if ((*p)->uid == uid)
|
if ((*p)->uid == uid)
|
||||||
return((*p)->name);
|
return((*p)->name);
|
||||||
p = &(*p)->next;
|
p = &(*p)->next;
|
||||||
}
|
}
|
||||||
*p = (struct pwbuf *) xmalloc(sizeof(struct pwbuf));
|
if (!(*p = (struct pwbuf *)malloc(sizeof(struct pwbuf))))
|
||||||
|
return ERRname;
|
||||||
(*p)->uid = uid;
|
(*p)->uid = uid;
|
||||||
pw = getpwuid(uid);
|
pw = getpwuid(uid);
|
||||||
if(!pw || strlen(pw->pw_name) >= P_G_SZ)
|
if(!pw || strlen(pw->pw_name) >= P_G_SZ)
|
||||||
sprintf((*p)->name, "%u", uid);
|
sprintf((*p)->name, "%u", uid);
|
||||||
else
|
else
|
||||||
strcpy((*p)->name, pw->pw_name);
|
strcpy((*p)->name, pw->pw_name);
|
||||||
|
|
||||||
@ -81,7 +83,8 @@ char *pwcache_get_group(gid_t gid) {
|
|||||||
return((*g)->name);
|
return((*g)->name);
|
||||||
g = &(*g)->next;
|
g = &(*g)->next;
|
||||||
}
|
}
|
||||||
*g = (struct grpbuf *) xmalloc(sizeof(struct grpbuf));
|
if (!(*g = (struct grpbuf *)malloc(sizeof(struct grpbuf))))
|
||||||
|
return ERRname;;
|
||||||
(*g)->gid = gid;
|
(*g)->gid = gid;
|
||||||
gr = getgrgid(gid);
|
gr = getgrgid(gid);
|
||||||
if (!gr || strlen(gr->gr_name) >= P_G_SZ)
|
if (!gr || strlen(gr->gr_name) >= P_G_SZ)
|
||||||
|
227
proc/readproc.c
227
proc/readproc.c
@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "readproc.h"
|
#include "readproc.h"
|
||||||
#include "alloc.h"
|
|
||||||
#include "escape.h"
|
#include "escape.h"
|
||||||
#include "pwcache.h"
|
#include "pwcache.h"
|
||||||
#include "devname.h"
|
#include "devname.h"
|
||||||
@ -149,7 +148,7 @@ typedef struct status_table_struct {
|
|||||||
// and the number of entries. Currently, the table is padded to 128
|
// and the number of entries. Currently, the table is padded to 128
|
||||||
// entries and we therefore mask with 127.
|
// entries and we therefore mask with 127.
|
||||||
|
|
||||||
static void status2proc(char *S, proc_t *restrict P, int is_proc){
|
static int status2proc (char *S, proc_t *restrict P, int is_proc) {
|
||||||
long Threads = 0;
|
long Threads = 0;
|
||||||
long Tgid = 0;
|
long Tgid = 0;
|
||||||
long Pid = 0;
|
long Pid = 0;
|
||||||
@ -279,8 +278,8 @@ ENTER(0x220);
|
|||||||
buf[u++] = c;
|
buf[u++] = c;
|
||||||
}
|
}
|
||||||
buf[u] = '\0';
|
buf[u] = '\0';
|
||||||
if (!P->cmd)
|
if (!P->cmd && !(P->cmd = strndup(buf, 15)))
|
||||||
P->cmd = strndup(buf, 15);
|
return 1;
|
||||||
S--; // put back the '\n' or '\0'
|
S--; // put back the '\n' or '\0'
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -391,7 +390,9 @@ ENTER(0x220);
|
|||||||
#else
|
#else
|
||||||
if (j) {
|
if (j) {
|
||||||
#endif
|
#endif
|
||||||
P->supgid = xmalloc(j+1); // +1 in case space disappears
|
P->supgid = malloc(j+1); // +1 in case space disappears
|
||||||
|
if (!P->supgid)
|
||||||
|
return 1;
|
||||||
memcpy(P->supgid, S, j);
|
memcpy(P->supgid, S, j);
|
||||||
if (' ' != P->supgid[--j]) ++j;
|
if (' ' != P->supgid[--j]) ++j;
|
||||||
P->supgid[j] = '\0'; // whack the space or the newline
|
P->supgid[j] = '\0'; // whack the space or the newline
|
||||||
@ -448,32 +449,39 @@ ENTER(0x220);
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FALSE_THREADS
|
#ifdef FALSE_THREADS
|
||||||
if (!P->supgid && !IS_THREAD(P))
|
if (!P->supgid && !IS_THREAD(P)) {
|
||||||
#else
|
#else
|
||||||
if (!P->supgid)
|
if (!P->supgid) {
|
||||||
#endif
|
#endif
|
||||||
P->supgid = xstrdup("-");
|
P->supgid = strdup("-");
|
||||||
|
if (!P->supgid)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
LEAVE(0x220);
|
LEAVE(0x220);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#undef GPERF_TABLE_SIZE
|
#undef GPERF_TABLE_SIZE
|
||||||
|
|
||||||
static void supgrps_from_supgids (proc_t *p) {
|
static int supgrps_from_supgids (proc_t *p) {
|
||||||
char *g, *s;
|
char *g, *s;
|
||||||
int t;
|
int t;
|
||||||
|
|
||||||
if (!p->supgid || '-' == *p->supgid) {
|
if (!p->supgid || '-' == *p->supgid) {
|
||||||
p->supgrp = xstrdup("-");
|
if (!(p->supgrp = strdup("-")))
|
||||||
return;
|
return 1;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
s = p->supgid;
|
s = p->supgid;
|
||||||
t = 0;
|
t = 0;
|
||||||
do {
|
do {
|
||||||
if (',' == *s) ++s;
|
if (',' == *s) ++s;
|
||||||
g = pwcache_get_group((uid_t)strtol(s, &s, 10));
|
g = pwcache_get_group((uid_t)strtol(s, &s, 10));
|
||||||
p->supgrp = xrealloc(p->supgrp, P_G_SZ+t+2);
|
if (!(p->supgrp = realloc(p->supgrp, P_G_SZ+t+2)))
|
||||||
|
return 1;
|
||||||
t += snprintf(p->supgrp+t, P_G_SZ+2, "%s%s", t ? "," : "", g);
|
t += snprintf(p->supgrp+t, P_G_SZ+2, "%s%s", t ? "," : "", g);
|
||||||
} while (*s);
|
} while (*s);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
@ -488,49 +496,66 @@ static inline void oomadj2proc(const char* S, proc_t *restrict P)
|
|||||||
}
|
}
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static void sd2proc(proc_t *restrict p) {
|
static int sd2proc (proc_t *restrict p) {
|
||||||
#ifdef WITH_SYSTEMD
|
#ifdef WITH_SYSTEMD
|
||||||
char buf[64];
|
char buf[64];
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
|
|
||||||
if (0 > sd_pid_get_machine_name(p->tid, &p->sd_mach))
|
if (0 > sd_pid_get_machine_name(p->tid, &p->sd_mach)) {
|
||||||
p->sd_mach = strdup("-");
|
if (!(p->sd_mach = strdup("-")))
|
||||||
|
return 1;
|
||||||
if (0 > sd_pid_get_owner_uid(p->tid, &uid))
|
}
|
||||||
p->sd_ouid = strdup("-");
|
if (0 > sd_pid_get_owner_uid(p->tid, &uid)) {
|
||||||
else {
|
if (!(p->sd_ouid = strdup("-")))
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
snprintf(buf, sizeof(buf), "%d", (int)uid);
|
snprintf(buf, sizeof(buf), "%d", (int)uid);
|
||||||
p->sd_ouid = strdup(buf);
|
if (!(p->sd_ouid = strdup(buf)))
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
if (0 > sd_pid_get_session(p->tid, &p->sd_sess)) {
|
if (0 > sd_pid_get_session(p->tid, &p->sd_sess)) {
|
||||||
p->sd_sess = strdup("-");
|
if (!(p->sd_sess = strdup("-")))
|
||||||
p->sd_seat = strdup("-");
|
return 1;
|
||||||
|
if (!(p->sd_seat = strdup("-")))
|
||||||
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
if (0 > sd_session_get_seat(p->sd_sess, &p->sd_seat))
|
if (0 > sd_session_get_seat(p->sd_sess, &p->sd_seat))
|
||||||
p->sd_seat = strdup("-");
|
if (!(p->sd_seat = strdup("-")))
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
if (0 > sd_pid_get_slice(p->tid, &p->sd_slice))
|
if (0 > sd_pid_get_slice(p->tid, &p->sd_slice))
|
||||||
p->sd_slice = strdup("-");
|
if (!(p->sd_slice = strdup("-")))
|
||||||
|
return 1;
|
||||||
if (0 > sd_pid_get_unit(p->tid, &p->sd_unit))
|
if (0 > sd_pid_get_unit(p->tid, &p->sd_unit))
|
||||||
p->sd_unit = strdup("-");
|
if (!(p->sd_unit = strdup("-")))
|
||||||
|
return 1;
|
||||||
if (0 > sd_pid_get_user_unit(p->tid, &p->sd_uunit))
|
if (0 > sd_pid_get_user_unit(p->tid, &p->sd_uunit))
|
||||||
p->sd_uunit = strdup("-");
|
if (!(p->sd_uunit = strdup("-")))
|
||||||
|
return 1;
|
||||||
#else
|
#else
|
||||||
p->sd_mach = strdup("?");
|
if (!(p->sd_mach = strdup("?")))
|
||||||
p->sd_ouid = strdup("?");
|
return 1;
|
||||||
p->sd_seat = strdup("?");
|
if (!(p->sd_ouid = strdup("?")))
|
||||||
p->sd_sess = strdup("?");
|
return 1;
|
||||||
p->sd_slice = strdup("?");
|
if (!(p->sd_seat = strdup("?")))
|
||||||
p->sd_unit = strdup("?");
|
return 1;
|
||||||
p->sd_uunit = strdup("?");
|
if (!(p->sd_sess = strdup("?")))
|
||||||
|
return 1;
|
||||||
|
if (!(p->sd_slice = strdup("?")))
|
||||||
|
return 1;
|
||||||
|
if (!(p->sd_unit = strdup("?")))
|
||||||
|
return 1;
|
||||||
|
if (!(p->sd_uunit = strdup("?")))
|
||||||
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
// Reads /proc/*/stat files, being careful not to trip over processes with
|
// Reads /proc/*/stat files, being careful not to trip over processes with
|
||||||
// names like ":-) 1 2 3 4 5 6".
|
// names like ":-) 1 2 3 4 5 6".
|
||||||
static void stat2proc(const char* S, proc_t *restrict P) {
|
static int stat2proc (const char* S, proc_t *restrict P) {
|
||||||
unsigned num;
|
unsigned num;
|
||||||
char* tmp;
|
char* tmp;
|
||||||
|
|
||||||
@ -546,8 +571,8 @@ ENTER(0x160);
|
|||||||
tmp = strrchr(S, ')');
|
tmp = strrchr(S, ')');
|
||||||
num = tmp - S;
|
num = tmp - S;
|
||||||
if(num >= 16) num = 15;
|
if(num >= 16) num = 15;
|
||||||
if (!P->cmd)
|
if (!P->cmd && !(P->cmd = strndup(S, num)))
|
||||||
P->cmd = strndup(S, num);
|
return 1;
|
||||||
S = tmp + 2; // skip ") "
|
S = tmp + 2; // skip ") "
|
||||||
|
|
||||||
num = sscanf(S,
|
num = sscanf(S,
|
||||||
@ -591,6 +616,7 @@ ENTER(0x160);
|
|||||||
P->nlwp = 1;
|
P->nlwp = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
LEAVE(0x160);
|
LEAVE(0x160);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -610,15 +636,21 @@ static int file2str(const char *directory, const char *what, struct utlbuf_s *ub
|
|||||||
/* on first use we preallocate a buffer of minimum size to emulate
|
/* on first use we preallocate a buffer of minimum size to emulate
|
||||||
former 'local static' behavior -- even if this read fails, that
|
former 'local static' behavior -- even if this read fails, that
|
||||||
buffer will likely soon be used for another subdirectory anyway
|
buffer will likely soon be used for another subdirectory anyway
|
||||||
( besides, with this xcalloc we will never need to use memcpy ) */
|
( besides, with the calloc call we will never need use memcpy ) */
|
||||||
if (ub->buf) ub->buf[0] = '\0';
|
if (ub->buf) ub->buf[0] = '\0';
|
||||||
else ub->buf = xcalloc((ub->siz = buffGRW));
|
else {
|
||||||
|
ub->buf = calloc(1, (ub->siz = buffGRW));
|
||||||
|
if (!ub->buf) return -1;
|
||||||
|
}
|
||||||
sprintf(path, "%s/%s", directory, what);
|
sprintf(path, "%s/%s", directory, what);
|
||||||
if (-1 == (fd = open(path, O_RDONLY, 0))) return -1;
|
if (-1 == (fd = open(path, O_RDONLY, 0))) return -1;
|
||||||
while (0 < (num = read(fd, ub->buf + tot_read, ub->siz - tot_read))) {
|
while (0 < (num = read(fd, ub->buf + tot_read, ub->siz - tot_read))) {
|
||||||
tot_read += num;
|
tot_read += num;
|
||||||
if (tot_read < ub->siz) break;
|
if (tot_read < ub->siz) break;
|
||||||
ub->buf = xrealloc(ub->buf, (ub->siz += buffGRW));
|
if (!(ub->buf = realloc(ub->buf, (ub->siz += buffGRW)))) {
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
ub->buf[tot_read] = '\0';
|
ub->buf[tot_read] = '\0';
|
||||||
close(fd);
|
close(fd);
|
||||||
@ -648,7 +680,8 @@ static char** file2strvec(const char* directory, const char* what) {
|
|||||||
}
|
}
|
||||||
if (end_of_file && (n == 0 || buf[n-1]))/* last read char not null */
|
if (end_of_file && (n == 0 || buf[n-1]))/* last read char not null */
|
||||||
buf[n++] = '\0'; /* so append null-terminator */
|
buf[n++] = '\0'; /* so append null-terminator */
|
||||||
rbuf = xrealloc(rbuf, tot + n); /* allocate more memory */
|
rbuf = realloc(rbuf, tot + n); /* allocate more memory */
|
||||||
|
if (!rbuf) return NULL;
|
||||||
memcpy(rbuf + tot, buf, n); /* copy buffer into it */
|
memcpy(rbuf + tot, buf, n); /* copy buffer into it */
|
||||||
tot += n; /* increment total byte ctr */
|
tot += n; /* increment total byte ctr */
|
||||||
if (end_of_file)
|
if (end_of_file)
|
||||||
@ -670,7 +703,8 @@ static char** file2strvec(const char* directory, const char* what) {
|
|||||||
}
|
}
|
||||||
c += sizeof(char*); /* one extra for NULL term */
|
c += sizeof(char*); /* one extra for NULL term */
|
||||||
|
|
||||||
rbuf = xrealloc(rbuf, tot + c + align); /* make room for ptrs AT END */
|
rbuf = realloc(rbuf, tot + c + align); /* make room for ptrs AT END */
|
||||||
|
if (!rbuf) return NULL;
|
||||||
endbuf = rbuf + tot; /* addr just past data buf */
|
endbuf = rbuf + tot; /* addr just past data buf */
|
||||||
q = ret = (char**) (endbuf+align); /* ==> free(*ret) to dealloc */
|
q = ret = (char**) (endbuf+align); /* ==> free(*ret) to dealloc */
|
||||||
*q++ = p = rbuf; /* point ptrs to the strings */
|
*q++ = p = rbuf; /* point ptrs to the strings */
|
||||||
@ -722,7 +756,7 @@ static int read_unvectored(char *restrict const dst, unsigned sz, const char* wh
|
|||||||
|
|
||||||
// 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 void fill_cgroup_cvt (const char* directory, proc_t *restrict p) {
|
static int fill_cgroup_cvt (const char* directory, proc_t *restrict p) {
|
||||||
#define vMAX ( MAX_BUFSZ - (int)(dst - dst_buffer) )
|
#define vMAX ( MAX_BUFSZ - (int)(dst - dst_buffer) )
|
||||||
char *src, *dst, *grp, *eob, *name;
|
char *src, *dst, *grp, *eob, *name;
|
||||||
int tot, x, whackable_int = MAX_BUFSZ;
|
int tot, x, whackable_int = MAX_BUFSZ;
|
||||||
@ -740,18 +774,20 @@ static void fill_cgroup_cvt (const char* directory, proc_t *restrict p) {
|
|||||||
dst += snprintf(dst, vMAX, "%s", (dst > dst_buffer) ? "," : "");
|
dst += snprintf(dst, vMAX, "%s", (dst > dst_buffer) ? "," : "");
|
||||||
dst += escape_str(dst, grp, vMAX, &whackable_int);
|
dst += escape_str(dst, grp, vMAX, &whackable_int);
|
||||||
}
|
}
|
||||||
p->cgroup = strdup(dst_buffer[0] ? dst_buffer : "-");
|
if (!(p->cgroup = strdup(dst_buffer[0] ? dst_buffer : "-")))
|
||||||
|
return 1;
|
||||||
name = strstr(p->cgroup, ":name=");
|
name = strstr(p->cgroup, ":name=");
|
||||||
if (name && *(name+6)) name += 6; else name = p->cgroup;
|
if (name && *(name+6)) name += 6; else name = p->cgroup;
|
||||||
p->cgname = strdup(name);
|
if (!(p->cgname = strdup(name)))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
#undef vMAX
|
#undef vMAX
|
||||||
}
|
}
|
||||||
|
|
||||||
// This routine reads a 'cmdline' for the designated proc_t, "escapes"
|
// This routine reads a 'cmdline' for the designated proc_t, "escapes"
|
||||||
// the result into a single string while guaranteeing the caller a
|
// the result into a single string while guaranteeing the caller a
|
||||||
// valid proc_t.cmdline pointer.
|
// valid proc_t.cmdline pointer.
|
||||||
static void fill_cmdline_cvt (const char* directory, proc_t *restrict p) {
|
static int fill_cmdline_cvt (const char* directory, proc_t *restrict p) {
|
||||||
#define uFLG ( ESC_BRACKETS | ESC_DEFUNCT )
|
#define uFLG ( ESC_BRACKETS | ESC_DEFUNCT )
|
||||||
int whackable_int = MAX_BUFSZ;
|
int whackable_int = MAX_BUFSZ;
|
||||||
|
|
||||||
@ -760,18 +796,24 @@ static void fill_cmdline_cvt (const char* directory, proc_t *restrict p) {
|
|||||||
else
|
else
|
||||||
escape_command(dst_buffer, p, MAX_BUFSZ, &whackable_int, uFLG);
|
escape_command(dst_buffer, p, MAX_BUFSZ, &whackable_int, uFLG);
|
||||||
p->cmdline = strdup(dst_buffer[0] ? dst_buffer : "?");
|
p->cmdline = strdup(dst_buffer[0] ? dst_buffer : "?");
|
||||||
|
if (!p->cmdline)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
#undef uFLG
|
#undef uFLG
|
||||||
}
|
}
|
||||||
|
|
||||||
// This routine reads an 'environ' for the designated proc_t and
|
// This routine reads an 'environ' for the designated proc_t and
|
||||||
// guarantees the caller a valid proc_t.environ pointer.
|
// guarantees the caller a valid proc_t.environ pointer.
|
||||||
static void fill_environ_cvt (const char* directory, proc_t *restrict p) {
|
static int fill_environ_cvt (const char* directory, proc_t *restrict p) {
|
||||||
int whackable_int = MAX_BUFSZ;
|
int whackable_int = MAX_BUFSZ;
|
||||||
|
|
||||||
dst_buffer[0] = '\0';
|
dst_buffer[0] = '\0';
|
||||||
if (read_unvectored(src_buffer, MAX_BUFSZ, directory, "environ", ' '))
|
if (read_unvectored(src_buffer, MAX_BUFSZ, directory, "environ", ' '))
|
||||||
escape_str(dst_buffer, src_buffer, MAX_BUFSZ, &whackable_int);
|
escape_str(dst_buffer, src_buffer, MAX_BUFSZ, &whackable_int);
|
||||||
p->environ = strdup(dst_buffer[0] ? dst_buffer : "-");
|
p->environ = strdup(dst_buffer[0] ? dst_buffer : "-");
|
||||||
|
if (!p->environ)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -781,6 +823,7 @@ static void fill_environ_cvt (const char* directory, proc_t *restrict p) {
|
|||||||
static char *lxc_containers (const char *path) {
|
static char *lxc_containers (const char *path) {
|
||||||
static struct utlbuf_s ub = { NULL, 0 }; // util buffer for whole cgroup
|
static struct utlbuf_s ub = { NULL, 0 }; // util buffer for whole cgroup
|
||||||
static char lxc_none[] = "-";
|
static char lxc_none[] = "-";
|
||||||
|
static char lxc_oops[] = "?"; // used when memory alloc fails
|
||||||
/*
|
/*
|
||||||
try to locate the lxc delimiter eyecatcher somewhere in a task's cgroup
|
try to locate the lxc delimiter eyecatcher somewhere in a task's cgroup
|
||||||
directory -- the following are from nested privileged plus unprivileged
|
directory -- the following are from nested privileged plus unprivileged
|
||||||
@ -821,8 +864,12 @@ static char *lxc_containers (const char *path) {
|
|||||||
return ele->name; // return just a recycled name
|
return ele->name; // return just a recycled name
|
||||||
ele = ele->next;
|
ele = ele->next;
|
||||||
}
|
}
|
||||||
ele = (struct lxc_ele *)xmalloc(sizeof(struct lxc_ele));
|
if (!(ele = (struct lxc_ele *)malloc(sizeof(struct lxc_ele))))
|
||||||
ele->name = xstrdup(p2);
|
return lxc_oops;
|
||||||
|
if (!(ele->name = strdup(p2))) {
|
||||||
|
free(ele);
|
||||||
|
return lxc_oops;
|
||||||
|
}
|
||||||
ele->next = anchor; // push the new container name
|
ele->next = anchor; // push the new container name
|
||||||
anchor = ele;
|
anchor = ele;
|
||||||
return ele->name; // return a new container name
|
return ele->name; // return a new container name
|
||||||
@ -862,6 +909,7 @@ static proc_t* simple_readproc(PROCTAB *restrict const PT, proc_t *restrict cons
|
|||||||
static struct stat sb; // stat() buffer
|
static struct stat sb; // stat() buffer
|
||||||
char *restrict const path = PT->path;
|
char *restrict const path = PT->path;
|
||||||
unsigned flags = PT->flags;
|
unsigned flags = PT->flags;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
if (stat(path, &sb) == -1) /* no such dirent (anymore) */
|
if (stat(path, &sb) == -1) /* no such dirent (anymore) */
|
||||||
goto next_proc;
|
goto next_proc;
|
||||||
@ -875,7 +923,7 @@ static proc_t* simple_readproc(PROCTAB *restrict const PT, proc_t *restrict cons
|
|||||||
if (flags & PROC_FILLSTAT) { // read /proc/#/stat
|
if (flags & PROC_FILLSTAT) { // read /proc/#/stat
|
||||||
if (file2str(path, "stat", &ub) == -1)
|
if (file2str(path, "stat", &ub) == -1)
|
||||||
goto next_proc;
|
goto next_proc;
|
||||||
stat2proc(ub.buf, p);
|
rc += stat2proc(ub.buf, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & PROC_FILLMEM) { // read /proc/#/statm
|
if (flags & PROC_FILLMEM) { // read /proc/#/statm
|
||||||
@ -885,9 +933,9 @@ static proc_t* simple_readproc(PROCTAB *restrict const PT, proc_t *restrict cons
|
|||||||
|
|
||||||
if (flags & PROC_FILLSTATUS) { // read /proc/#/status
|
if (flags & PROC_FILLSTATUS) { // read /proc/#/status
|
||||||
if (file2str(path, "status", &ub) != -1){
|
if (file2str(path, "status", &ub) != -1){
|
||||||
status2proc(ub.buf, p, 1);
|
rc += status2proc(ub.buf, p, 1);
|
||||||
if (flags & PROC_FILLSUPGRP)
|
if (flags & PROC_FILLSUPGRP)
|
||||||
supgrps_from_supgids(p);
|
rc += supgrps_from_supgids(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -921,17 +969,17 @@ 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");
|
p->environ_v = file2strvec(path, "environ");
|
||||||
if (flags & PROC_EDITENVRCVT)
|
if (flags & PROC_EDITENVRCVT)
|
||||||
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");
|
p->cmdline_v = file2strvec(path, "cmdline");
|
||||||
if (flags & PROC_EDITCMDLCVT)
|
if (flags & PROC_EDITCMDLCVT)
|
||||||
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");
|
p->cgroup_v = file2strvec(path, "cgroup");
|
||||||
if (flags & PROC_EDITCGRPCVT)
|
if (flags & PROC_EDITCGRPCVT)
|
||||||
fill_cgroup_cvt(path, p);
|
rc += fill_cgroup_cvt(path, p);
|
||||||
|
|
||||||
if (flags & PROC_FILLOOM) {
|
if (flags & PROC_FILLOOM) {
|
||||||
if (file2str(path, "oom_score", &ub) != -1)
|
if (file2str(path, "oom_score", &ub) != -1)
|
||||||
@ -945,12 +993,13 @@ static proc_t* simple_readproc(PROCTAB *restrict const PT, proc_t *restrict cons
|
|||||||
|
|
||||||
|
|
||||||
if (flags & PROC_FILLSYSTEMD) // get sd-login.h stuff
|
if (flags & PROC_FILLSYSTEMD) // get sd-login.h stuff
|
||||||
sd2proc(p);
|
rc += sd2proc(p);
|
||||||
|
|
||||||
if (flags & PROC_FILL_LXC) // value the lxc name
|
if (flags & PROC_FILL_LXC) // value the lxc name
|
||||||
p->lxcname = lxc_containers(path);
|
p->lxcname = lxc_containers(path);
|
||||||
|
|
||||||
return p;
|
if (rc == 0) return p;
|
||||||
|
errno = ENOMEM;
|
||||||
next_proc:
|
next_proc:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -968,6 +1017,7 @@ static proc_t* simple_readtask(PROCTAB *restrict const PT, const proc_t *restric
|
|||||||
static struct utlbuf_s ub = { NULL, 0 }; // buf for stat,statm,status
|
static struct utlbuf_s ub = { NULL, 0 }; // buf for stat,statm,status
|
||||||
static struct stat sb; // stat() buffer
|
static struct stat sb; // stat() buffer
|
||||||
unsigned flags = PT->flags;
|
unsigned flags = PT->flags;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
if (stat(path, &sb) == -1) /* no such dirent (anymore) */
|
if (stat(path, &sb) == -1) /* no such dirent (anymore) */
|
||||||
goto next_task;
|
goto next_task;
|
||||||
@ -981,7 +1031,7 @@ static proc_t* simple_readtask(PROCTAB *restrict const PT, const proc_t *restric
|
|||||||
if (flags & PROC_FILLSTAT) { // read /proc/#/task/#/stat
|
if (flags & PROC_FILLSTAT) { // read /proc/#/task/#/stat
|
||||||
if (file2str(path, "stat", &ub) == -1)
|
if (file2str(path, "stat", &ub) == -1)
|
||||||
goto next_task;
|
goto next_task;
|
||||||
stat2proc(ub.buf, t);
|
rc += stat2proc(ub.buf, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FALSE_THREADS
|
#ifdef FALSE_THREADS
|
||||||
@ -989,16 +1039,16 @@ static proc_t* simple_readtask(PROCTAB *restrict const PT, const proc_t *restric
|
|||||||
MK_THREAD(t);
|
MK_THREAD(t);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (flags & PROC_FILLMEM) // read /proc/#/task/#statm
|
if (flags & PROC_FILLMEM) { // read /proc/#/task/#statm
|
||||||
if (file2str(path, "statm", &ub) != -1)
|
if (file2str(path, "statm", &ub) != -1)
|
||||||
statm2proc(ub.buf, t);
|
statm2proc(ub.buf, t);
|
||||||
|
}
|
||||||
if (flags & PROC_FILLSTATUS) { // read /proc/#/task/#/status
|
if (flags & PROC_FILLSTATUS) { // read /proc/#/task/#/status
|
||||||
if (file2str(path, "status", &ub) != -1) {
|
if (file2str(path, "status", &ub) != -1) {
|
||||||
status2proc(ub.buf, t, 0);
|
rc += status2proc(ub.buf, t, 0);
|
||||||
#ifndef FALSE_THREADS
|
#ifndef FALSE_THREADS
|
||||||
if (flags & PROC_FILLSUPGRP)
|
if (flags & PROC_FILLSUPGRP)
|
||||||
supgrps_from_supgids(t);
|
rc += supgrps_from_supgids(t);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1028,25 +1078,25 @@ static proc_t* simple_readtask(PROCTAB *restrict const PT, const proc_t *restric
|
|||||||
#ifdef FALSE_THREADS
|
#ifdef FALSE_THREADS
|
||||||
if (!p) {
|
if (!p) {
|
||||||
if (flags & PROC_FILLSUPGRP)
|
if (flags & PROC_FILLSUPGRP)
|
||||||
supgrps_from_supgids(t);
|
rc += supgrps_from_supgids(t);
|
||||||
#endif
|
#endif
|
||||||
if (flags & PROC_FILLENV) // read /proc/#/task/#/environ
|
if (flags & PROC_FILLENV) // read /proc/#/task/#/environ
|
||||||
t->environ_v = file2strvec(path, "environ");
|
t->environ_v = file2strvec(path, "environ");
|
||||||
if (flags & PROC_EDITENVRCVT)
|
if (flags & PROC_EDITENVRCVT)
|
||||||
fill_environ_cvt(path, t);
|
rc += fill_environ_cvt(path, t);
|
||||||
|
|
||||||
if (flags & PROC_FILLARG) // read /proc/#/task/#/cmdline
|
if (flags & PROC_FILLARG) // read /proc/#/task/#/cmdline
|
||||||
t->cmdline_v = file2strvec(path, "cmdline");
|
t->cmdline_v = file2strvec(path, "cmdline");
|
||||||
if (flags & PROC_EDITCMDLCVT)
|
if (flags & PROC_EDITCMDLCVT)
|
||||||
fill_cmdline_cvt(path, t);
|
rc += fill_cmdline_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");
|
t->cgroup_v = file2strvec(path, "cgroup");
|
||||||
if (flags & PROC_EDITCGRPCVT)
|
if (flags & PROC_EDITCGRPCVT)
|
||||||
fill_cgroup_cvt(path, t);
|
rc += fill_cgroup_cvt(path, t);
|
||||||
|
|
||||||
if (flags & PROC_FILLSYSTEMD) // get sd-login.h stuff
|
if (flags & PROC_FILLSYSTEMD) // get sd-login.h stuff
|
||||||
sd2proc(t);
|
rc += sd2proc(t);
|
||||||
|
|
||||||
#ifdef FALSE_THREADS
|
#ifdef FALSE_THREADS
|
||||||
} else {
|
} else {
|
||||||
@ -1082,7 +1132,8 @@ static proc_t* simple_readtask(PROCTAB *restrict const PT, const proc_t *restric
|
|||||||
if (flags & PROC_FILL_LXC)
|
if (flags & PROC_FILL_LXC)
|
||||||
t->lxcname = lxc_containers(path);
|
t->lxcname = lxc_containers(path);
|
||||||
|
|
||||||
return t;
|
if (rc == 0) return t;
|
||||||
|
errno = ENOMEM;
|
||||||
next_task:
|
next_task:
|
||||||
#ifndef FALSE_THREADS
|
#ifndef FALSE_THREADS
|
||||||
(void)p;
|
(void)p;
|
||||||
@ -1172,10 +1223,13 @@ proc_t* readproc(PROCTAB *restrict const PT, proc_t *restrict p) {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
saved_p = p;
|
saved_p = p;
|
||||||
if(!p) p = xcalloc(sizeof *p);
|
if (p) free_acquired(p, 1);
|
||||||
else free_acquired(p, 1);
|
else {
|
||||||
|
p = calloc(1, sizeof *p);
|
||||||
|
if (!p) goto out;
|
||||||
|
}
|
||||||
for(;;){
|
for(;;){
|
||||||
|
if (errno == ENOMEM) goto out;
|
||||||
// fills in the path, plus p->tid and p->tgid
|
// fills in the path, plus p->tid and p->tgid
|
||||||
if (!PT->finder(PT,p)) goto out;
|
if (!PT->finder(PT,p)) goto out;
|
||||||
|
|
||||||
@ -1203,13 +1257,17 @@ proc_t* readeither (PROCTAB *restrict const PT, proc_t *restrict x) {
|
|||||||
proc_t *saved_x, *ret;
|
proc_t *saved_x, *ret;
|
||||||
|
|
||||||
saved_x = x;
|
saved_x = x;
|
||||||
if (!x) x = xcalloc(sizeof(*x));
|
if (x) free_acquired(x,1);
|
||||||
else free_acquired(x,1);
|
else {
|
||||||
|
x = calloc(1, sizeof(*x));
|
||||||
|
if (!x) goto end_procs;
|
||||||
|
}
|
||||||
if (new_p) goto next_task;
|
if (new_p) goto next_task;
|
||||||
|
|
||||||
next_proc:
|
next_proc:
|
||||||
new_p = NULL;
|
new_p = NULL;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
if (errno == ENOMEM) goto end_procs;
|
||||||
// fills in the PT->path, plus skel_p.tid and skel_p.tgid
|
// fills in the PT->path, plus skel_p.tid and skel_p.tgid
|
||||||
if (!PT->finder(PT,&skel_p)) goto end_procs; // simple_nextpid
|
if (!PT->finder(PT,&skel_p)) goto end_procs; // simple_nextpid
|
||||||
if (!task_dir_missing) break;
|
if (!task_dir_missing) break;
|
||||||
@ -1238,8 +1296,10 @@ PROCTAB* openproc(unsigned flags, ...) {
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
struct stat sbuf;
|
struct stat sbuf;
|
||||||
static int did_stat;
|
static int did_stat;
|
||||||
PROCTAB* PT = xmalloc(sizeof(PROCTAB));
|
PROCTAB* PT = malloc(sizeof(PROCTAB));
|
||||||
|
|
||||||
|
if (!PT)
|
||||||
|
return NULL;
|
||||||
if (!did_stat){
|
if (!did_stat){
|
||||||
task_dir_missing = stat("/proc/self/task", &sbuf);
|
task_dir_missing = stat("/proc/self/task", &sbuf);
|
||||||
did_stat = 1;
|
did_stat = 1;
|
||||||
@ -1269,10 +1329,13 @@ PROCTAB* openproc(unsigned flags, ...) {
|
|||||||
}
|
}
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
if (!src_buffer){
|
if (!src_buffer
|
||||||
src_buffer = xmalloc(MAX_BUFSZ);
|
&& !(src_buffer = malloc(MAX_BUFSZ)))
|
||||||
dst_buffer = xmalloc(MAX_BUFSZ);
|
return NULL;
|
||||||
}
|
if (!dst_buffer
|
||||||
|
&& !(dst_buffer = malloc(MAX_BUFSZ)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
return PT;
|
return PT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1288,15 +1351,17 @@ void closeproc(PROCTAB* PT) {
|
|||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
void look_up_our_self(proc_t *p) {
|
int look_up_our_self(proc_t *p) {
|
||||||
struct utlbuf_s ub = { NULL, 0 };
|
struct utlbuf_s ub = { NULL, 0 };
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
if(file2str("/proc/self", "stat", &ub) == -1){
|
if(file2str("/proc/self", "stat", &ub) == -1){
|
||||||
fprintf(stderr, "Error, do this: mount -t proc proc /proc\n");
|
fprintf(stderr, "Error, do this: mount -t proc proc /proc\n");
|
||||||
_exit(47);
|
_exit(47);
|
||||||
}
|
}
|
||||||
stat2proc(ub.buf, p); // parse /proc/self/stat
|
rc = stat2proc(ub.buf, p); // parse /proc/self/stat
|
||||||
free(ub.buf);
|
free(ub.buf);
|
||||||
|
return !rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef MK_THREAD
|
#undef MK_THREAD
|
||||||
|
@ -33,7 +33,6 @@ __BEGIN_DECLS
|
|||||||
// Most of it comes from task_struct in linux/sched.h
|
// Most of it comes from task_struct in linux/sched.h
|
||||||
//
|
//
|
||||||
typedef struct proc_t {
|
typedef struct proc_t {
|
||||||
// 1st 16 bytes
|
|
||||||
int
|
int
|
||||||
tid, // (special) task id, the POSIX thread ID (see also: tgid)
|
tid, // (special) task id, the POSIX thread ID (see also: tgid)
|
||||||
ppid; // stat,status pid of parent process
|
ppid; // stat,status pid of parent process
|
||||||
@ -46,11 +45,9 @@ typedef struct proc_t {
|
|||||||
#endif
|
#endif
|
||||||
pad_2, // n/a padding
|
pad_2, // n/a padding
|
||||||
pad_3; // n/a padding
|
pad_3; // n/a padding
|
||||||
// 2nd 16 bytes
|
|
||||||
unsigned long long
|
unsigned long long
|
||||||
utime, // stat user-mode CPU time accumulated by process
|
utime, // stat user-mode CPU time accumulated by process
|
||||||
stime, // stat kernel-mode CPU time accumulated by process
|
stime, // stat kernel-mode CPU time accumulated by process
|
||||||
// and so on...
|
|
||||||
cutime, // stat cumulative utime of process and reaped children
|
cutime, // stat cumulative utime of process and reaped children
|
||||||
cstime, // stat cumulative stime of process and reaped children
|
cstime, // stat cumulative stime of process and reaped children
|
||||||
start_time, // stat start time of process -- seconds since 1-1-70
|
start_time, // stat start time of process -- seconds since 1-1-70
|
||||||
@ -64,7 +61,7 @@ typedef struct proc_t {
|
|||||||
#ifdef SIGNAL_STRING
|
#ifdef SIGNAL_STRING
|
||||||
char
|
char
|
||||||
// Linux 2.1.7x and up have 64 signals. Allow 64, plus '\0' and padding.
|
// Linux 2.1.7x and up have 64 signals. Allow 64, plus '\0' and padding.
|
||||||
signal[18], // status mask of pending signals, per-task for readtask() but per-proc for readproc()
|
signal[18], // status mask of pending signals
|
||||||
blocked[18], // status mask of blocked signals
|
blocked[18], // status mask of blocked signals
|
||||||
sigignore[18], // status mask of ignored signals
|
sigignore[18], // status mask of ignored signals
|
||||||
sigcatch[18], // status mask of caught signals
|
sigcatch[18], // status mask of caught signals
|
||||||
@ -72,7 +69,7 @@ typedef struct proc_t {
|
|||||||
#else
|
#else
|
||||||
long long
|
long long
|
||||||
// Linux 2.1.7x and up have 64 signals.
|
// Linux 2.1.7x and up have 64 signals.
|
||||||
signal, // status mask of pending signals, per-task for readtask() but per-proc for readproc()
|
signal, // status mask of pending signals
|
||||||
blocked, // status mask of blocked signals
|
blocked, // status mask of blocked signals
|
||||||
sigignore, // status mask of ignored signals
|
sigignore, // status mask of ignored signals
|
||||||
sigcatch, // status mask of caught signals
|
sigcatch, // status mask of caught signals
|
||||||
@ -258,7 +255,7 @@ PROCTAB* openproc(unsigned flags, ... /* pid_t*|uid_t*|dev_t*|char* [, int n] */
|
|||||||
// with the previous process or thread.
|
// with the previous process or thread.
|
||||||
proc_t* readproc(PROCTAB *__restrict const PT, proc_t *__restrict p);
|
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);
|
||||||
void look_up_our_self(proc_t *p);
|
int look_up_our_self(proc_t *p);
|
||||||
void closeproc(PROCTAB* PT);
|
void closeproc(PROCTAB* PT);
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
#ifdef __CYGWIN__
|
#ifdef __CYGWIN__
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#endif
|
#endif
|
||||||
#include "alloc.h"
|
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "sysinfo.h" /* include self to verify prototypes */
|
#include "sysinfo.h" /* include self to verify prototypes */
|
||||||
#include "procps-private.h"
|
#include "procps-private.h"
|
||||||
@ -126,57 +125,24 @@ PROCPS_EXPORT int procps_loadavg(
|
|||||||
double *restrict av15)
|
double *restrict av15)
|
||||||
{
|
{
|
||||||
double avg_1=0, avg_5=0, avg_15=0;
|
double avg_1=0, avg_5=0, avg_15=0;
|
||||||
char *savelocale;
|
char savelocale[128];
|
||||||
int retval=0;
|
int retval=0;
|
||||||
|
|
||||||
FILE_TO_BUF(LOADAVG_FILE,loadavg_fd);
|
FILE_TO_BUF(LOADAVG_FILE,loadavg_fd);
|
||||||
savelocale = strdup(setlocale(LC_NUMERIC, NULL));
|
snprintf(savelocale, sizeof(savelocale), "%s", setlocale(LC_NUMERIC, NULL));
|
||||||
setlocale(LC_NUMERIC, "C");
|
setlocale(LC_NUMERIC, "C");
|
||||||
if (sscanf(buf, "%lf %lf %lf", &avg_1, &avg_5, &avg_15) < 3) {
|
if (sscanf(buf, "%lf %lf %lf", &avg_1, &avg_5, &avg_15) < 3) {
|
||||||
|
setlocale(LC_NUMERIC, savelocale);
|
||||||
retval = -ERANGE;
|
retval = -ERANGE;
|
||||||
}
|
}
|
||||||
setlocale(LC_NUMERIC, savelocale);
|
setlocale(LC_NUMERIC, savelocale);
|
||||||
free(savelocale);
|
|
||||||
SET_IF_DESIRED(av1, avg_1);
|
SET_IF_DESIRED(av1, avg_1);
|
||||||
SET_IF_DESIRED(av5, avg_5);
|
SET_IF_DESIRED(av5, avg_5);
|
||||||
SET_IF_DESIRED(av15, avg_15);
|
SET_IF_DESIRED(av15, avg_15);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char buff[BUFFSIZE]; /* used in the procedures */
|
|
||||||
/***********************************************************************/
|
|
||||||
|
|
||||||
static void crash(const char *filename) {
|
|
||||||
perror(filename);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// based on Fabian Frederick's /proc/slabinfo parser
|
|
||||||
|
|
||||||
unsigned int getslabinfo (struct slab_cache **slab){
|
|
||||||
FILE* fd;
|
|
||||||
int cSlab = 0;
|
|
||||||
buff[BUFFSIZE-1] = 0;
|
|
||||||
*slab = NULL;
|
|
||||||
fd = fopen("/proc/slabinfo", "rb");
|
|
||||||
if(!fd) crash("/proc/slabinfo");
|
|
||||||
while (fgets(buff,BUFFSIZE-1,fd)){
|
|
||||||
if(!memcmp("slabinfo - version:",buff,19)) continue; // skip header
|
|
||||||
if(*buff == '#') continue; // skip comments
|
|
||||||
(*slab) = xrealloc(*slab, (cSlab+1)*sizeof(struct slab_cache));
|
|
||||||
sscanf(buff, "%47s %u %u %u %u", // allow 47; max seen is 24
|
|
||||||
(*slab)[cSlab].name,
|
|
||||||
&(*slab)[cSlab].active_objs,
|
|
||||||
&(*slab)[cSlab].num_objs,
|
|
||||||
&(*slab)[cSlab].objsize,
|
|
||||||
&(*slab)[cSlab].objperslab
|
|
||||||
) ;
|
|
||||||
cSlab++;
|
|
||||||
}
|
|
||||||
fclose(fd);
|
|
||||||
return cSlab;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PROCFS_PID_MAX "/proc/sys/kernel/pid_max"
|
#define PROCFS_PID_MAX "/proc/sys/kernel/pid_max"
|
||||||
#define DEFAULT_PID_LENGTH 5
|
#define DEFAULT_PID_LENGTH 5
|
||||||
@ -219,7 +185,7 @@ PROCPS_EXPORT unsigned int procps_pid_length(void)
|
|||||||
*/
|
*/
|
||||||
long procps_cpu_count(void)
|
long procps_cpu_count(void)
|
||||||
{
|
{
|
||||||
long cpus=1;
|
long cpus;
|
||||||
|
|
||||||
cpus = sysconf(_SC_NPROCESSORS_ONLN);
|
cpus = sysconf(_SC_NPROCESSORS_ONLN);
|
||||||
if (cpus < 1)
|
if (cpus < 1)
|
||||||
|
@ -6,25 +6,10 @@
|
|||||||
#include <features.h>
|
#include <features.h>
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
|
|
||||||
extern int have_privs; /* boolean, true if setuid or similar */
|
|
||||||
|
|
||||||
long procps_cpu_count(void);
|
long procps_cpu_count(void);
|
||||||
long procps_hertz_get(void);
|
long procps_hertz_get(void);
|
||||||
int procps_loadavg(double *av1, double *av5, double *av15);
|
int procps_loadavg(double *av1, double *av5, double *av15);
|
||||||
unsigned int procps_pid_length(void);
|
unsigned int procps_pid_length(void);
|
||||||
|
|
||||||
#define BUFFSIZE (64*1024)
|
|
||||||
|
|
||||||
typedef struct slab_cache{
|
|
||||||
char name[48];
|
|
||||||
unsigned active_objs;
|
|
||||||
unsigned num_objs;
|
|
||||||
unsigned objsize;
|
|
||||||
unsigned objperslab;
|
|
||||||
}slab_cache;
|
|
||||||
|
|
||||||
extern unsigned int getslabinfo (struct slab_cache**);
|
|
||||||
|
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
#endif /* SYSINFO_H */
|
#endif /* SYSINFO_H */
|
||||||
|
@ -70,23 +70,21 @@ PROCPS_EXPORT int procps_uptime(
|
|||||||
double *restrict idle_secs)
|
double *restrict idle_secs)
|
||||||
{
|
{
|
||||||
double up=0, idle=0;
|
double up=0, idle=0;
|
||||||
char *savelocale;
|
char savelocale[128];
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
if ((fp = fopen(UPTIME_FILE, "r")) == NULL)
|
if ((fp = fopen(UPTIME_FILE, "r")) == NULL)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
savelocale = strdup(setlocale(LC_NUMERIC, NULL));
|
snprintf(savelocale, sizeof(savelocale), "%s", setlocale(LC_NUMERIC, NULL));
|
||||||
setlocale(LC_NUMERIC, "C");
|
setlocale(LC_NUMERIC, "C");
|
||||||
if (fscanf(fp, "%lf %lf", &up, &idle) < 2) {
|
if (fscanf(fp, "%lf %lf", &up, &idle) < 2) {
|
||||||
setlocale(LC_NUMERIC, savelocale);
|
setlocale(LC_NUMERIC, savelocale);
|
||||||
free(savelocale);
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
setlocale(LC_NUMERIC, savelocale);
|
setlocale(LC_NUMERIC, savelocale);
|
||||||
free(savelocale);
|
|
||||||
if (uptime_secs)
|
if (uptime_secs)
|
||||||
*uptime_secs = up;
|
*uptime_secs = up;
|
||||||
if (idle_secs)
|
if (idle_secs)
|
||||||
|
Loading…
Reference in New Issue
Block a user