From ed594723073ff0cdd3cb4914a9147f5a136b5263 Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Fri, 2 Dec 2011 03:47:19 -0600 Subject: [PATCH] library: provide for huge cmdlines, like old libproc The CodingStyle document suggests programs should allow for cmdlines of at least 128k. Only the ps program can display such a cmdline, and only with multiple -w switches. The library function file2strvec can essentially return a cmdline of unlimited length. However, the library function fill_cmdline_cvt used an arbitrary upper limit of 2048 for buffers automatically allocated on the stack. This patch raises the fill_cmdline_cvt upper limit to 128k via dymaically acquired utility buffers ensured by the openproc function. It also makes indentation consistent in the openproc function. --- proc/readproc.c | 50 +++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/proc/readproc.c b/proc/readproc.c index 0a59f54a..9dff16da 100644 --- a/proc/readproc.c +++ b/proc/readproc.c @@ -42,6 +42,12 @@ extern void __cyg_profile_func_enter(void*,void*); #define IS_THREAD(q) ( q->pad_1 == '\xee' ) #endif +// utility buffers of MAX_BUFSZ bytes each, available to +// any function following an openproc() call +static char *src_buffer, + *dst_buffer; +#define MAX_BUFSZ 1024*64*2 + #ifndef SIGNAL_STRING // convert hex string to unsigned long long static unsigned long long unhex(const char *restrict cp){ @@ -660,14 +666,13 @@ static void fill_cgroup_cvt (const char* directory, proc_t *restrict p) { // and guarantees the caller a valid proc_t.cmdline pointer. static void fill_cmdline_cvt (const char* directory, proc_t *restrict p) { #define uFLG ( ESC_BRACKETS | ESC_DEFUNCT ) - char sbuf[2048], dbuf[2048]; - int whackable_int = sizeof(dbuf); + int whackable_int = MAX_BUFSZ; - if (read_unvectored(sbuf, sizeof(sbuf), directory, "cmdline", ' ')) - escape_str(dbuf, sbuf, sizeof(dbuf), &whackable_int); + if (read_unvectored(src_buffer, MAX_BUFSZ, directory, "cmdline", ' ')) + escape_str(dst_buffer, src_buffer, MAX_BUFSZ, &whackable_int); else - escape_command(dbuf, p, sizeof(dbuf), &whackable_int, uFLG); - p->cmdline = vectorize_this_str(dbuf); + escape_command(dst_buffer, p, MAX_BUFSZ, &whackable_int, uFLG); + p->cmdline = vectorize_this_str(dst_buffer); #undef uFLG } @@ -1135,9 +1140,9 @@ PROCTAB* openproc(int flags, ...) { static int did_stat; PROCTAB* PT = xmalloc(sizeof(PROCTAB)); - if(!did_stat){ - task_dir_missing = stat("/proc/self/task", &sbuf); - did_stat = 1; + if (!did_stat){ + task_dir_missing = stat("/proc/self/task", &sbuf); + did_stat = 1; } PT->taskdir = NULL; PT->taskdir_user = -1; @@ -1146,24 +1151,28 @@ PROCTAB* openproc(int flags, ...) { PT->reader = simple_readproc; if (flags & PROC_PID){ - PT->procfs = NULL; - PT->finder = listed_nextpid; + PT->procfs = NULL; + PT->finder = listed_nextpid; }else{ - PT->procfs = opendir("/proc"); - if(!PT->procfs) { free(PT); return NULL; } - PT->finder = simple_nextpid; + PT->procfs = opendir("/proc"); + if (!PT->procfs) { free(PT); return NULL; } + PT->finder = simple_nextpid; } PT->flags = flags; - va_start(ap, flags); /* Init args list */ + va_start(ap, flags); if (flags & PROC_PID) - PT->pids = va_arg(ap, pid_t*); - else if (flags & PROC_UID) { - PT->uids = va_arg(ap, uid_t*); - PT->nuid = va_arg(ap, int); + PT->pids = va_arg(ap, pid_t*); + else if (flags & PROC_UID){ + PT->uids = va_arg(ap, uid_t*); + PT->nuid = va_arg(ap, int); } - va_end(ap); /* Clean up args list */ + va_end(ap); + if (!src_buffer){ + src_buffer = xmalloc(MAX_BUFSZ); + dst_buffer = xmalloc(MAX_BUFSZ); + } return PT; } @@ -1365,3 +1374,4 @@ proc_t * get_proc_stats(pid_t pid, proc_t *p) { #undef MK_THREAD #undef IS_THREAD +#undef MAX_BUFSZ -- 2.40.0