New function to get the full and short cmdline (Linux)

(Old svn revision: 5191)
This commit is contained in:
Mike Massonnet
2008-08-03 20:02:28 +00:00
parent f61e15b987
commit f3c2ad4706
3 changed files with 152 additions and 87 deletions

View File

@@ -1,3 +1,7 @@
2008-08-03 Mike Massonnet <mmassonnet@xfce.org>
* New function to get the full and short cmdline (Linux)
2008-08-02 Mike Massonnet <mmassonnet@xfce.org> 2008-08-02 Mike Massonnet <mmassonnet@xfce.org>
* Display memory less than 1 MB with two decimals like 0.00 MB * Display memory less than 1 MB with two decimals like 0.00 MB

View File

@@ -29,6 +29,92 @@
static gint pagesize = 0; static gint pagesize = 0;
static void get_cmdline(gint pid, gchar *cmdline, gint length, gchar *cmdline_full, gint length_full)
{
FILE *file;
char filename[255];
char *p;
int c;
int i = 0;
char buffer[4096];
int idummy;
snprintf (filename, 255, "/proc/%i/cmdline", pid);
file = fopen (filename, "r");
if (file == NULL) {
return;
}
/* read byte per byte until EOF */
while (EOF != (c = fgetc (file))) {
if (c != 0) {
cmdline_full[i++] = c;
} else {
cmdline_full[i++] = ' ';
}
if (i == length_full - 1) {
break;
}
}
if (cmdline_full[i-1] == ' ') {
cmdline_full[i-1] = '\0';
} else {
cmdline_full[i] = '\0';
}
fclose (file);
/* daemon processes and kernel processes don't have a cmdline */
if (i == 0) {
/* read from /proc/pid/stat and enclose with brakets */
snprintf (filename, 255, "/proc/%i/stat", pid);
file = fopen (filename, "r");
if (file == NULL) {
return;
}
fgets (buffer, sizeof (buffer), file);
fclose (file);
cmdline_full[0] = '[';
sscanf (buffer, "%i (%252s", &idummy, &cmdline_full[1]);
if (NULL != (strrchr (cmdline_full, ')'))) {
*strrchr (cmdline_full, ')') = '\0';
}
i = strlen (cmdline_full);
cmdline_full[i] = ']';
cmdline_full[i+1] = '\0';
strncpy (cmdline, cmdline_full, length);
return;
}
/* get the short version */
snprintf (filename, 255, "/proc/%i/cmdline", pid);
file = fopen (filename, "r");
fgets (cmdline, length, file);
fclose (file);
p = strchr (cmdline, ':');
if (NULL != p) {
*p = '\0';
} else {
p = strrchr (cmdline, '/');
if (NULL != p) {
strncpy (cmdline, p+1, length);
}
}
if (cmdline[0] == '-') {
for (i = 0; cmdline[i] != '\0'; i++) {
cmdline[i] = cmdline[i+1];
}
}
}
static struct task get_task_details(gint pid) static struct task get_task_details(gint pid)
{ {
FILE *task_file; FILE *task_file;
@@ -42,14 +128,17 @@ static struct task get_task_details(gint pid)
gchar filename[255]; gchar filename[255];
gchar cmdline_filename[255]; gchar cmdline_filename[255];
gint utime = 0;
gint stime = 0;
sprintf(filename, "/proc/%i/stat", pid); sprintf(filename, "/proc/%i/stat", pid);
sprintf(cmdline_filename, "/proc/%i/cmdline", pid); sprintf(cmdline_filename, "/proc/%i/cmdline", pid);
stat(filename, &status);
task.pid = -1; task.pid = -1;
task.checked = FALSE; task.checked = FALSE;
stat(filename, &status);
if (pagesize == 0) if (pagesize == 0)
{ {
pagesize = sysconf(_SC_PAGESIZE); pagesize = sysconf(_SC_PAGESIZE);
@@ -57,104 +146,75 @@ static struct task get_task_details(gint pid)
pagesize = 4*1024; pagesize = 4*1024;
} }
if(NULL == (task_file = fopen(filename,"r")))
return task;
if((task_file = fopen(filename,"r")) != NULL) fgets(buffer_status, sizeof(buffer_status), task_file);
{ fclose(task_file);
gint utime = 0;
gint stime = 0;
fgets(buffer_status, sizeof(buffer_status), task_file); sscanf(buffer_status, "%i (%255s %1s %i %i %i %i %i %255s %255s %255s %255s %255s %i %i %i %i %i %i %i %i %i %i %i %255s %255s %255s %i %255s %255s %255s %255s %255s %255s %255s %255s %255s %255s %i %255s %255s",
&task.pid, // processid
dummy, // processname
task.state, // processstate
&task.ppid, // parentid
&idummy, // processs groupid
sscanf(buffer_status, "%i (%255s %1s %i %i %i %i %i %255s %255s %255s %255s %255s %i %i %i %i %i %i %i %i %i %i %i %255s %255s %255s %i %255s %255s %255s %255s %255s %255s %255s %255s %255s %255s %i %255s %255s", &idummy, // session id
&task.pid, // processid &idummy, // tty id
task.name, // processname &idummy, // tpgid: The process group ID of the process running on tty of the process
task.state, // processstate dummy, // flags
&task.ppid, // parentid dummy, // minflt minor faults the process has maid
&idummy, // processs groupid
&idummy, // session id dummy, // cminflt
&idummy, // tty id dummy, // majflt
&idummy, // tpgid: The process group ID of the process running on tty of the process dummy, // cmajflt
dummy, // flags &utime, // utime the number of jiffies that this process has scheduled in user mode
dummy, // minflt minor faults the process has maid &stime, // stime " kernel mode
dummy, // cminflt &idummy, // cutime " waited for children in user
dummy, // majflt &idummy, // cstime " kernel mode
dummy, // cmajflt &idummy, // priority (nice value + fifteen)
&utime, // utime the number of jiffies that this process has scheduled in user mode &task.prio, // nice range from 19 to -19 /* my change */
&stime, // stime " kernel mode &idummy, // hardcoded 0
&idummy, // cutime " waited for children in user &idummy, // itrealvalue time in jiffies to next SIGALRM send to this process
&idummy, // cstime " kernel mode &idummy, // starttime jiffies the process startet after system boot
&idummy, // priority (nice value + fifteen) &task.vsize, // vsize in bytes
&task.prio, // nice range from 19 to -19 /* my change */ &task.rss, // rss (number of pages in real memory)
&idummy, // hardcoded 0 dummy, // rlim limit in bytes for rss
&idummy, // itrealvalue time in jiffies to next SIGALRM send to this process dummy, // startcode
&idummy, // starttime jiffies the process startet after system boot dummy, // endcode
&task.vsize, // vsize in bytes &idummy, // startstack
&task.rss, // rss (number of pages in real memory) dummy, // kstkesp value of esp (stack pointer)
dummy, // rlim limit in bytes for rss dummy, // kstkeip value of EIP (instruction pointer)
dummy, // startcode dummy, // signal. bitmap of pending signals
dummy, // endcode dummy, // blocked: bitmap of blocked signals
&idummy, // startstack dummy, // sigignore: bitmap of ignored signals
dummy, // kstkesp value of esp (stack pointer) dummy, // sigcatch: bitmap of catched signals
dummy, // kstkeip value of EIP (instruction pointer) dummy, // wchan
dummy, // signal. bitmap of pending signals dummy, // nswap
dummy, // blocked: bitmap of blocked signals dummy, // cnswap
dummy, // sigignore: bitmap of ignored signals dummy, // exit_signal
dummy, // sigcatch: bitmap of catched signals &idummy, // CPU number last executed on
dummy, // wchan dummy,
dummy, // nswap dummy
dummy, // cnswap );
dummy, // exit_signal
&idummy, // CPU number last executed on
dummy,
dummy task.old_time = task.time;
); task.time = stime + utime;
task.time_percentage = 0;
task.rss *= pagesize;
task.old_time = task.time; task.uid = status.st_uid;
task.time = stime + utime; passwdp = getpwuid(task.uid);
task.time_percentage = 0; if(passwdp != NULL && passwdp->pw_name != NULL)
task.rss *= pagesize; g_strlcpy(task.uname, passwdp->pw_name, sizeof(task.uname));
task.uid = status.st_uid; get_cmdline(pid, task.name, sizeof(task.name), task.fullname, sizeof(task.fullname));
passwdp = getpwuid(task.uid);
if(passwdp != NULL && passwdp->pw_name != NULL)
g_strlcpy(task.uname, passwdp->pw_name, sizeof(task.uname));
}
if(task_file != NULL)
fclose(task_file);
if((cmdline_file = fopen(cmdline_filename,"r")) != NULL)
{
gchar dummy[255];
strcpy(dummy, "");
fscanf(cmdline_file, "%255s", dummy);
if(strcmp(dummy, "") != 0)
{
if(g_strrstr(dummy,"/") != NULL)
g_strlcpy(task.name, g_strrstr(dummy,"/")+1, 255);
else
g_strlcpy(task.name, dummy, 255);
// workaround for cmd-line entries with leading "-"
if(g_str_has_prefix(task.name, "-"))
sscanf(task.name, "-%255s", task.name);
}
}
if(cmdline_file != NULL)
fclose(cmdline_file);
if(g_str_has_suffix(task.name, ")"))
*g_strrstr(task.name, ")") = '\0';
return task; return task;
} }

View File

@@ -32,6 +32,7 @@ struct task
gint uid; gint uid;
gchar uname[64]; gchar uname[64];
gchar name[64]; gchar name[64];
gchar fullname[255];
gchar state[16]; gchar state[16];
gint vsize; gint vsize;
gint rss; gint rss;