From 887bb51016253e82ae26fe9d78bc7a5dfbe2ef85 Mon Sep 17 00:00:00 2001 From: Craig Small Date: Sun, 17 Apr 2016 14:14:27 +1000 Subject: [PATCH] library: cleanup of readproc functions readproc still had some of the old API hanging around that was good while we were trying it out, but its time to say goodbye: readproc.h removed from public procps.h header file enum ns_type - not used - removed get_ns_name() - not defined - removed get_ns_id() - not defined - removed PROCTAB proc_t only used internal to library readproctab() and 2,3 friends not used - removed proc_data_t was used by readproctab23() - removed readtask() - not used - removed read_cmdline() - copy,renamed and made generic - remove original freeproc() - not used - removed get_proc_status - not used - removed, however there should be a new function created that does this. Given a PID return data about it instead of scanning the entire procfs. Maybe it already does. Left as internal-to-library only functions: readproc(), readeither(), look_up_our_self(), openproc(), closeproc() Updated libprocps.sym to export only what we use. --- proc/devname.h | 2 +- proc/libprocps.sym | 10 -- proc/procps.h | 1 - proc/readproc.c | 237 --------------------------------------------- proc/readproc.h | 86 ++++------------ 5 files changed, 22 insertions(+), 314 deletions(-) diff --git a/proc/devname.h b/proc/devname.h index 7aa1f408..1c6e39ff 100644 --- a/proc/devname.h +++ b/proc/devname.h @@ -9,7 +9,7 @@ __BEGIN_DECLS #define ABBREV_TTY 2 /* remove tty */ #define ABBREV_PTS 4 /* remove pts/ */ -extern unsigned dev_to_tty(char *__restrict ret, unsigned chop, dev_t dev_t_dev, int pid, unsigned int flags); +unsigned dev_to_tty(char *__restrict ret, unsigned chop, dev_t dev_t_dev, int pid, unsigned int flags); __END_DECLS #endif diff --git a/proc/libprocps.sym b/proc/libprocps.sym index 77a1bda4..64bb9c7c 100644 --- a/proc/libprocps.sym +++ b/proc/libprocps.sym @@ -1,20 +1,10 @@ LIBPROCPS_0 { global: - closeproc; - dev_to_tty; escape_command; escape_str; escape_strlist; escaped_copy; fatal_proc_unmounted; - look_up_our_self; - lookup_wchan; - openproc; - readproc; - readproctab2; - readproctab3; - readproctab; - readtask; procps_cpu_count; procps_diskstat_dev_count; procps_diskstat_dev_get; diff --git a/proc/procps.h b/proc/procps.h index 2bf042e7..03a38206 100644 --- a/proc/procps.h +++ b/proc/procps.h @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/proc/readproc.c b/proc/readproc.c index 99f5b9d0..f044b442 100644 --- a/proc/readproc.c +++ b/proc/readproc.c @@ -784,13 +784,6 @@ static void fill_environ_cvt (const char* directory, proc_t *restrict p) { 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]; - snprintf(path, sizeof(path), "/proc/%u", pid); - return read_unvectored(dst, sz, path, "cmdline", ' '); -} - // Provide the means to value proc_t.lxcname (perhaps only with "-") while // tracking all names already seen thus avoiding the overhead of repeating @@ -1235,61 +1228,6 @@ out: return NULL; } -////////////////////////////////////////////////////////////////////////////////// -// readtask: return a pointer to a proc_t filled with requested info about the -// next task available. If no more such tasks are available, return a null -// pointer (boolean false). Use the passed buffer instead of allocating -// space if it is non-NULL. -proc_t* readtask(PROCTAB *restrict const PT, const proc_t *restrict const p, proc_t *restrict t) { - char path[PROCPATHLEN]; // must hold /proc/2000222000/task/2000222000/cmdline - proc_t *ret; - proc_t *saved_t; - - saved_t = t; - if(!t) t = xcalloc(sizeof *t); - else free_acquired(t, 1); - - // 1. got to fake a thread for old kernels -#ifdef QUICK_THREADS - // 2. for single-threaded processes, this is faster (but must patch up stuff that differs!) - if(task_dir_missing || p->nlwp < 2){ -#else - if(task_dir_missing){ -#endif - if(PT->did_fake) goto out; - PT->did_fake=1; - memcpy(t,p,sizeof(proc_t)); - // use the per-task pending, not per-tgid pending -#ifdef SIGNAL_STRING - memcpy(&t->signal, &t->_sigpnd, sizeof t->signal); -#else - t->signal = t->_sigpnd; -#endif -#ifdef QUICK_THREADS - MK_THREAD(t); -#else - t->environ = NULL; - t->cmdline = vectorize_this_str("n/a"); - t->cgroup = NULL; - t->supgid = NULL; - t->supgrp = NULL; -#endif - return t; - } - - for(;;){ - // fills in the path, plus t->tid and t->tgid - if (unlikely(!PT->taskfinder(PT,p,t,path))) goto out; // simple_nexttid - - // go read the task data - ret = PT->taskreader(PT,p,t,path); // simple_readtask - if(ret) return ret; - } - -out: - if(!saved_t) free(t); - return NULL; -} ////////////////////////////////////////////////////////////////////////////////// // readeither: return a pointer to a proc_t filled with requested info about @@ -1386,14 +1324,6 @@ void closeproc(PROCTAB* PT) { } } -// deallocate space allocated by readproc -void freeproc(proc_t* p) { - if (p) { - free_acquired(p, 0); - free(p); - } -} - ////////////////////////////////////////////////////////////////////////////////// void look_up_our_self(proc_t *p) { @@ -1407,173 +1337,6 @@ void look_up_our_self(proc_t *p) { free(ub.buf); } - -/* Convenient wrapper around openproc and readproc to slurp in the whole process - * table subset satisfying the constraints of flags and the optional PID list. - * Free allocated memory with exit(). Access via tab[N]->member. The pointer - * list is NULL terminated. - */ -proc_t** readproctab(unsigned flags, ...) { - PROCTAB* PT = NULL; - proc_t** tab = NULL; - int n = 0; - va_list ap; - - va_start(ap, flags); /* pass through args to openproc */ - if (flags & PROC_UID) { - /* temporary variables to ensure that va_arg() instances - * are called in the right order - */ - uid_t* u; - int i; - - u = va_arg(ap, uid_t*); - i = va_arg(ap, int); - PT = openproc(flags, u, i); - } - else if (flags & PROC_PID) - PT = openproc(flags, va_arg(ap, void*)); /* assume ptr sizes same */ - else - PT = openproc(flags); - va_end(ap); - if (!PT) - return 0; - do { /* read table: */ - tab = xrealloc(tab, (n+1)*sizeof(proc_t*));/* realloc as we go, using */ - tab[n] = readproc(PT, NULL); /* final null to terminate */ - } while (tab[n++]); /* stop when NULL reached */ - closeproc(PT); - return tab; -} - -// Try again, this time with threads and selection. -proc_data_t *readproctab2(int(*want_proc)(proc_t *buf), int(*want_task)(proc_t *buf), PROCTAB *restrict const PT) { - static proc_data_t pd; - proc_t** ptab = NULL; - unsigned n_proc_alloc = 0; - unsigned n_proc = 0; - - proc_t** ttab = NULL; - unsigned n_task_alloc = 0; - unsigned n_task = 0; - - proc_t* data = NULL; - unsigned n_alloc = 0; - unsigned long n_used = 0; - - for(;;){ - proc_t *tmp; - if(n_alloc == n_used){ - //proc_t *old = data; - n_alloc = n_alloc*5/4+30; // grow by over 25% - data = xrealloc(data,sizeof(proc_t)*n_alloc); - memset(data+n_used, 0, sizeof(proc_t)*(n_alloc-n_used)); - } - if(n_proc_alloc == n_proc){ - //proc_t **old = ptab; - n_proc_alloc = n_proc_alloc*5/4+30; // grow by over 25% - ptab = xrealloc(ptab,sizeof(proc_t*)*n_proc_alloc); - } - tmp = readproc(PT, data+n_used); - if(!tmp) break; - if(!want_proc(tmp)) continue; - ptab[n_proc++] = (proc_t*)(n_used++); - if(!( PT->flags & PROC_LOOSE_TASKS )) continue; - for(;;){ - proc_t *t; - if(n_alloc == n_used){ - proc_t *old = data; - n_alloc = n_alloc*5/4+30; // grow by over 25% - data = xrealloc(data,sizeof(proc_t)*n_alloc); - // have to move tmp too - tmp = data+(tmp-old); - memset(data+n_used+1, 0, sizeof(proc_t)*(n_alloc-(n_used+1))); - } - if(n_task_alloc == n_task){ - //proc_t **old = ttab; - n_task_alloc = n_task_alloc*5/4+1; // grow by over 25% - ttab = xrealloc(ttab,sizeof(proc_t*)*n_task_alloc); - } - t = readtask(PT, tmp, data+n_used); - if(!t) break; - if(!want_task(t)) continue; - ttab[n_task++] = (proc_t*)(n_used++); - } - } - - pd.proc = ptab; - pd.task = ttab; - pd.nproc = n_proc; - pd.ntask = n_task; - if(PT->flags & PROC_LOOSE_TASKS){ - pd.tab = ttab; - pd.n = n_task; - }else{ - pd.tab = ptab; - pd.n = n_proc; - } - // change array indexes to pointers - while(n_proc--) ptab[n_proc] = data+(long)(ptab[n_proc]); - while(n_task--) ttab[n_task] = data+(long)(ttab[n_task]); - - return &pd; -} - -// Try try yet again, this time treating processes and threads the same... -proc_data_t *readproctab3 (int(*want_task)(proc_t *buf), PROCTAB *restrict const PT) { - static proc_data_t pd; - proc_t **tab = NULL; - unsigned n_alloc = 0; - unsigned n_used = 0; - proc_t *p = NULL; - - for (;;) { - if (n_alloc == n_used) { - n_alloc = n_alloc*5/4+30; // grow by over 25% - tab = xrealloc(tab,sizeof(proc_t*)*n_alloc); - } - // let this next guy allocate the necessary proc_t storage - // (or recycle it) since he can't tolerate realloc relocations - if (!(p = readeither(PT,p))) break; - if (want_task(p)) { - tab[n_used++] = p; - p = NULL; - } - } - - pd.tab = tab; - pd.n = n_used; - return &pd; -} - -/* - * get_proc_stats - lookup a single tasks information and fill out a proc_t - * - * On failure, returns NULL. On success, returns 'p' and 'p' is a valid - * and filled out proc_t structure. - */ -proc_t * get_proc_stats(pid_t pid, proc_t *p) { - struct utlbuf_s ub = { NULL, 0 }; - static char path[32]; - struct stat statbuf; - - sprintf(path, "/proc/%d", pid); - if (stat(path, &statbuf)) { - perror("stat"); - return NULL; - } - - if (file2str(path, "stat", &ub) >= 0) - stat2proc(ub.buf, p); - if (file2str(path, "statm", &ub) >= 0) - statm2proc(ub.buf, p); - if (file2str(path, "status", &ub) >= 0) - status2proc(ub.buf, p, 0); - - free(ub.buf); - return p; -} - #undef MK_THREAD #undef IS_THREAD #undef MAX_BUFSZ diff --git a/proc/readproc.h b/proc/readproc.h index 3fd7007a..6344de82 100644 --- a/proc/readproc.h +++ b/proc/readproc.h @@ -10,7 +10,9 @@ // in the file COPYING -// #include +#include +#include +#include #include #define SIGNAL_STRING @@ -31,18 +33,6 @@ __BEGIN_DECLS // neither tgid nor tid seemed correct. (in other words, FIXME) #define XXXID tid -enum ns_type { - IPCNS = 0, - MNTNS, - NETNS, - PIDNS, - USERNS, - UTSNS, - NUM_NS // total namespaces (fencepost) -}; -extern const char *get_ns_name(int id); -extern int get_ns_id(const char *name); - // Basic data structure which holds all information we can get about a process. // (unless otherwise specified, fields are read from /proc/#/stat) // @@ -183,10 +173,6 @@ typedef struct proc_t { // from openproc(). The setup is intentionally similar to the dirent interface // and other system table interfaces (utmp+wtmp come to mind). -#include -#include -#include - #define PROCPATHLEN 64 // must hold /proc/2000222000/task/2000222000/cmdline typedef struct PROCTAB { @@ -211,54 +197,6 @@ typedef struct PROCTAB { unsigned pathlen; // length of string in the above (w/o '\0') } PROCTAB; -// Initialize a PROCTAB structure holding needed call-to-call persistent data -extern PROCTAB* openproc(unsigned flags, ... /* pid_t*|uid_t*|dev_t*|char* [, int n] */ ); - -typedef struct proc_data_t { // valued by: (else zero) - proc_t **tab; // readproctab2, readproctab3 - proc_t **proc; // readproctab2 - proc_t **task; // * readproctab2 - int n; // readproctab2, readproctab3 - int nproc; // readproctab2 - int ntask; // * readproctab2 -} proc_data_t; // * when PROC_LOOSE_TASKS set - -extern proc_data_t *readproctab2(int(*want_proc)(proc_t *buf), int(*want_task)(proc_t *buf), PROCTAB *__restrict const PT); -extern proc_data_t *readproctab3(int(*want_task)(proc_t *buf), PROCTAB *__restrict const PT); - -// Convenient wrapper around openproc and readproc to slurp in the whole process -// table subset satisfying the constraints of flags and the optional PID list. -// Free allocated memory with exit(). Access via tab[N]->member. The pointer -// list is NULL terminated. -extern proc_t** readproctab(unsigned flags, ... /* same as openproc */ ); - -// Clean-up open files, etc from the openproc() -extern void closeproc(PROCTAB* PT); - -// Retrieve the next process or task matching the criteria set by the openproc(). -// -// Note: When NULL is used as the readproc 'p', readtask 't' or readeither 'x' -// parameter, the library will allocate the necessary proc_t storage. -// -// Alternatively, you may provide your own reuseable buffer address -// in which case that buffer *MUST* be initialized to zero one time -// only before first use. Thereafter, the library will manage such -// a passed proc_t, freeing any additional acquired memory associated -// with the previous process or thread. -extern proc_t* readproc(PROCTAB *__restrict const PT, proc_t *__restrict p); -extern proc_t* readtask(PROCTAB *__restrict const PT, const proc_t *__restrict const p, proc_t *__restrict t); -extern proc_t* readeither(PROCTAB *__restrict const PT, proc_t *__restrict x); - -// warning: interface may change -extern int read_cmdline(char *__restrict const dst, unsigned sz, unsigned pid); - -extern void look_up_our_self(proc_t *p); - -// Deallocate space allocated by readproc -extern void freeproc(proc_t* p); - -// Fill out a proc_t for a single task -extern proc_t * get_proc_stats(pid_t pid, proc_t *p); // openproc/readproctab: // @@ -305,5 +243,23 @@ extern proc_t * get_proc_stats(pid_t pid, proc_t *p); #define PROC_SPARE_3 0x04000000 #define PROC_SPARE_4 0x08000000 +// Function definitions +// Initialize a PROCTAB structure holding needed call-to-call persistent data +PROCTAB* openproc(unsigned flags, ... /* pid_t*|uid_t*|dev_t*|char* [, int n] */ ); +// Retrieve the next process or task matching the criteria set by the openproc(). +// +// Note: When NULL is used as the readproc 'p' or readeither 'x' +// parameter, the library will allocate the necessary proc_t storage. +// +// Alternatively, you may provide your own reuseable buffer address +// in which case that buffer *MUST* be initialized to zero one time +// only before first use. Thereafter, the library will manage such +// a passed proc_t, freeing any additional acquired memory associated +// with the previous process or thread. +proc_t* readproc(PROCTAB *__restrict const PT, proc_t *__restrict p); +proc_t* readeither(PROCTAB *__restrict const PT, proc_t *__restrict x); +void look_up_our_self(proc_t *p); +void closeproc(PROCTAB* PT); + __END_DECLS #endif -- 2.40.0