Commit cc23d13f authored by Michael Klein's avatar Michael Klein
Browse files

Add Platform_getProcessEnv

- currently implemented for darwin and linux
parent 0919ea32
#include "EnvScreen.h" #include "EnvScreen.h"
#include "config.h"
#include "CRT.h" #include "CRT.h"
#include "IncSet.h" #include "IncSet.h"
#include "ListItem.h" #include "ListItem.h"
#include "Platform.h"
#include "StringUtils.h" #include "StringUtils.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <unistd.h> #include <unistd.h>
/*{ /*{
...@@ -65,50 +65,14 @@ static void EnvScreen_scan(EnvScreen* this, Vector* lines, IncSet* inc) { ...@@ -65,50 +65,14 @@ static void EnvScreen_scan(EnvScreen* this, Vector* lines, IncSet* inc) {
Panel_prune(panel); Panel_prune(panel);
if (uid == 0 || uid == this->process->st_uid) { if (uid == 0 || uid == this->process->st_uid) {
long argmax = sysconf(_SC_ARG_MAX); char *env = Platform_getProcessEnv(this->process->pid);
char* buf = malloc(argmax); if (env) {
size_t bufsz = argmax; for (char *p = env; *p; p = strrchr(p, 0)+1)
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)); addLine(p, lines, panel, IncSet_filter(inc));
free(env);
} }
else { else {
addLine("Could not allocate memory.", lines, panel, IncSet_filter(inc)); addLine("Could not read process environment.", 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));
} }
} }
else { else {
......
...@@ -236,3 +236,56 @@ void Platform_setSwapValues(Meter* mtr) { ...@@ -236,3 +236,56 @@ void Platform_setSwapValues(Meter* mtr) {
mtr->total = swapused.xsu_total / 1024; mtr->total = swapused.xsu_total / 1024;
mtr->values[0] = swapused.xsu_used / 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;
}
...@@ -44,4 +44,6 @@ void Platform_setMemoryValues(Meter* mtr); ...@@ -44,4 +44,6 @@ void Platform_setMemoryValues(Meter* mtr);
void Platform_setSwapValues(Meter* mtr); void Platform_setSwapValues(Meter* mtr);
char* Platform_getProcessEnv(pid_t pid);
#endif #endif
...@@ -157,3 +157,8 @@ void Platform_setSwapValues(Meter* this) { ...@@ -157,3 +157,8 @@ void Platform_setSwapValues(Meter* this) {
void Platform_setTasksValues(Meter* this) { void Platform_setTasksValues(Meter* this) {
// TODO // TODO
} }
char* Platform_getProcessEnv(pid_t pid) {
// TODO
return NULL;
}
...@@ -25,6 +25,9 @@ in the source distribution for its full text. ...@@ -25,6 +25,9 @@ in the source distribution for its full text.
#include <math.h> #include <math.h>
#include <assert.h> #include <assert.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
/*{ /*{
#include "Action.h" #include "Action.h"
...@@ -205,3 +208,28 @@ void Platform_setSwapValues(Meter* this) { ...@@ -205,3 +208,28 @@ void Platform_setSwapValues(Meter* this) {
this->total = pl->totalSwap; this->total = pl->totalSwap;
this->values[0] = pl->usedSwap; 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;
}
...@@ -39,4 +39,6 @@ void Platform_setMemoryValues(Meter* this); ...@@ -39,4 +39,6 @@ void Platform_setMemoryValues(Meter* this);
void Platform_setSwapValues(Meter* this); void Platform_setSwapValues(Meter* this);
char* Platform_getProcessEnv(pid_t pid);
#endif #endif
...@@ -295,3 +295,8 @@ void Platform_setSwapValues(Meter* this) { ...@@ -295,3 +295,8 @@ void Platform_setSwapValues(Meter* this) {
void Platform_setTasksValues(Meter* this) { void Platform_setTasksValues(Meter* this) {
// TODO // TODO
} }
char* Platform_getProcessEnv(pid_t pid) {
// TODO
return NULL;
}
...@@ -131,3 +131,6 @@ bool Process_isThread(Process* this) { ...@@ -131,3 +131,6 @@ bool Process_isThread(Process* this) {
return false; return false;
} }
char* Platform_getProcessEnv(pid_t pid) {
return NULL;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment