diff --git a/EnvScreen.c b/EnvScreen.c index 1076ed0a..c989d26f 100644 --- a/EnvScreen.c +++ b/EnvScreen.c @@ -1,14 +1,14 @@ #include "EnvScreen.h" +#include "config.h" #include "CRT.h" #include "IncSet.h" #include "ListItem.h" +#include "Platform.h" #include "StringUtils.h" #include #include -#include -#include #include /*{ @@ -65,51 +65,15 @@ static void EnvScreen_scan(EnvScreen* this, Vector* lines, IncSet* inc) { Panel_prune(panel); if (uid == 0 || uid == this->process->st_uid) { - long argmax = sysconf(_SC_ARG_MAX); - char* buf = malloc(argmax); - size_t bufsz = argmax; - if (buf) { - int mib[3]; - mib[0] = CTL_KERN; - mib[1] = KERN_PROCARGS2; - mib[2] = this->process->pid; - bufsz = argmax; - if (sysctl(mib, 3, buf, &bufsz, 0, 0) == 0) { - if (bufsz > sizeof(int)) { - char *p = buf, *endp = buf + bufsz; - int argc = *(int*)p; - p += sizeof(int); - - // skip exe - p = strchr(p, 0)+1; - - // skip padding - while(!*p && p < endp) - ++p; - - // skip argv - for (; argc-- && p < endp; p = strrchr(p, 0)+1) - ; - - // skip padding - while(!*p && p < endp) - ++p; - - for (; *p && p < endp; p = strrchr(p, 0)+1) - addLine(p, lines, panel, IncSet_filter(inc)); - } - else { - addLine("Could not allocate memory.", lines, panel, IncSet_filter(inc)); - } - } - else { - addLine("sysctl(KERN_PROCARGS2) failed.", lines, panel, IncSet_filter(inc)); - } - free(buf); - } - else { - addLine("Out of memory.", lines, panel, IncSet_filter(inc)); - } + char *env = Platform_getProcessEnv(this->process->pid); + if (env) { + for (char *p = env; *p; p = strrchr(p, 0)+1) + addLine(p, lines, panel, IncSet_filter(inc)); + free(env); + } + else { + addLine("Could not read process environment.", lines, panel, IncSet_filter(inc)); + } } else { addLine("Process belongs to different user.", lines, panel, IncSet_filter(inc)); diff --git a/darwin/Platform.c b/darwin/Platform.c index 73b47c4c..c025509f 100644 --- a/darwin/Platform.c +++ b/darwin/Platform.c @@ -236,3 +236,56 @@ void Platform_setSwapValues(Meter* mtr) { mtr->total = swapused.xsu_total / 1024; mtr->values[0] = swapused.xsu_used / 1024; } + +char* Platform_getProcessEnv(pid_t pid) { + char* env = NULL; + + int argmax; + size_t bufsz = sizeof(argmax); + + int mib[3]; + mib[0] = CTL_KERN; + mib[1] = KERN_ARGMAX; + if (sysctl(mib, 2, &argmax, &bufsz, 0, 0) == 0) { + char* buf = malloc(argmax); + if (buf) { + mib[0] = CTL_KERN; + mib[1] = KERN_PROCARGS2; + mib[2] = pid; + size_t bufsz = argmax; + if (sysctl(mib, 3, buf, &bufsz, 0, 0) == 0) { + if (bufsz > sizeof(int)) { + char *p = buf, *endp = buf + bufsz; + int argc = *(int*)p; + p += sizeof(int); + + // skip exe + p = strchr(p, 0)+1; + + // skip padding + while(!*p && p < endp) + ++p; + + // skip argv + for (; argc-- && p < endp; p = strrchr(p, 0)+1) + ; + + // skip padding + while(!*p && p < endp) + ++p; + + size_t size = endp - p; + env = malloc(size+2); + if (env) { + memcpy(env, p, size); + env[size] = 0; + env[size+1] = 0; + } + } + } + free(buf); + } + } + + return env; +} diff --git a/darwin/Platform.h b/darwin/Platform.h index d1b9ea5e..0a873bf5 100644 --- a/darwin/Platform.h +++ b/darwin/Platform.h @@ -44,4 +44,6 @@ void Platform_setMemoryValues(Meter* mtr); void Platform_setSwapValues(Meter* mtr); +char* Platform_getProcessEnv(pid_t pid); + #endif diff --git a/freebsd/Platform.c b/freebsd/Platform.c index b1703291..46bef992 100644 --- a/freebsd/Platform.c +++ b/freebsd/Platform.c @@ -157,3 +157,8 @@ void Platform_setSwapValues(Meter* this) { void Platform_setTasksValues(Meter* this) { // TODO } + +char* Platform_getProcessEnv(pid_t pid) { + // TODO + return NULL; +} diff --git a/linux/Platform.c b/linux/Platform.c index 3a919bb1..81c96e4c 100644 --- a/linux/Platform.c +++ b/linux/Platform.c @@ -25,6 +25,9 @@ in the source distribution for its full text. #include #include +#include +#include +#include /*{ #include "Action.h" @@ -205,3 +208,28 @@ void Platform_setSwapValues(Meter* this) { this->total = pl->totalSwap; this->values[0] = pl->usedSwap; } + +char* Platform_getProcessEnv(pid_t pid) { + char procname[32+1]; + snprintf(procname, 32, "/proc/%d/environ", pid); + FILE* fd = fopen(procname, "r"); + char *env = NULL; + if (fd) { + size_t capacity = 4096, size = 0, bytes; + env = malloc(capacity); + while (env && (bytes = fread(env+size, 1, capacity-size, fd)) > 0) { + size += bytes; + capacity *= 2; + env = realloc(env, capacity); + } + fclose(fd); + if (size < 2 || env[size-1] || env[size-2]) { + if (size + 2 < capacity) { + env = realloc(env, capacity+2); + } + env[size] = 0; + env[size+1] = 0; + } + } + return env; +} diff --git a/linux/Platform.h b/linux/Platform.h index 2c79b299..114b9a20 100644 --- a/linux/Platform.h +++ b/linux/Platform.h @@ -39,4 +39,6 @@ void Platform_setMemoryValues(Meter* this); void Platform_setSwapValues(Meter* this); +char* Platform_getProcessEnv(pid_t pid); + #endif diff --git a/openbsd/Platform.c b/openbsd/Platform.c index 7114d941..90fbd2bc 100644 --- a/openbsd/Platform.c +++ b/openbsd/Platform.c @@ -295,3 +295,8 @@ void Platform_setSwapValues(Meter* this) { void Platform_setTasksValues(Meter* this) { // TODO } + +char* Platform_getProcessEnv(pid_t pid) { + // TODO + return NULL; +} diff --git a/unsupported/Platform.c b/unsupported/Platform.c index 5dd2e8f8..0f1ba97d 100644 --- a/unsupported/Platform.c +++ b/unsupported/Platform.c @@ -131,3 +131,6 @@ bool Process_isThread(Process* this) { return false; } +char* Platform_getProcessEnv(pid_t pid) { + return NULL; +}