From f3c2ad47067cd1ecbc6b625220de0eb7526bf0d5 Mon Sep 17 00:00:00 2001 From: Mike Massonnet Date: Sun, 3 Aug 2008 20:02:28 +0000 Subject: [PATCH] New function to get the full and short cmdline (Linux) (Old svn revision: 5191) --- ChangeLog | 4 + src/taskmanager-linux.c | 234 +++++++++++++++++++++++++--------------- src/types.h | 1 + 3 files changed, 152 insertions(+), 87 deletions(-) diff --git a/ChangeLog b/ChangeLog index bd54bc5..f24bf80 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2008-08-03 Mike Massonnet + + * New function to get the full and short cmdline (Linux) + 2008-08-02 Mike Massonnet * Display memory less than 1 MB with two decimals like 0.00 MB diff --git a/src/taskmanager-linux.c b/src/taskmanager-linux.c index 64e17e3..b8cc2d2 100644 --- a/src/taskmanager-linux.c +++ b/src/taskmanager-linux.c @@ -29,6 +29,92 @@ 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) { FILE *task_file; @@ -42,14 +128,17 @@ static struct task get_task_details(gint pid) gchar filename[255]; gchar cmdline_filename[255]; + gint utime = 0; + gint stime = 0; + sprintf(filename, "/proc/%i/stat", pid); sprintf(cmdline_filename, "/proc/%i/cmdline", pid); - stat(filename, &status); - task.pid = -1; task.checked = FALSE; + stat(filename, &status); + if (pagesize == 0) { pagesize = sysconf(_SC_PAGESIZE); @@ -57,104 +146,75 @@ static struct task get_task_details(gint pid) pagesize = 4*1024; } + if(NULL == (task_file = fopen(filename,"r"))) + return task; - if((task_file = fopen(filename,"r")) != NULL) - { - gint utime = 0; - gint stime = 0; + fgets(buffer_status, sizeof(buffer_status), task_file); + fclose(task_file); - 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", - &task.pid, // processid - task.name, // processname - task.state, // processstate - &task.ppid, // parentid - &idummy, // processs groupid + &idummy, // session id + &idummy, // tty id + &idummy, // tpgid: The process group ID of the process running on tty of the process + dummy, // flags + dummy, // minflt minor faults the process has maid - &idummy, // session id - &idummy, // tty id - &idummy, // tpgid: The process group ID of the process running on tty of the process - dummy, // flags - dummy, // minflt minor faults the process has maid + dummy, // cminflt + dummy, // majflt + dummy, // cmajflt + &utime, // utime the number of jiffies that this process has scheduled in user mode + &stime, // stime " kernel mode - dummy, // cminflt - dummy, // majflt - dummy, // cmajflt - &utime, // utime the number of jiffies that this process has scheduled in user mode - &stime, // stime " kernel mode + &idummy, // cutime " waited for children in user + &idummy, // cstime " kernel mode + &idummy, // priority (nice value + fifteen) + &task.prio, // nice range from 19 to -19 /* my change */ + &idummy, // hardcoded 0 - &idummy, // cutime " waited for children in user - &idummy, // cstime " kernel mode - &idummy, // priority (nice value + fifteen) - &task.prio, // nice range from 19 to -19 /* my change */ - &idummy, // hardcoded 0 + &idummy, // itrealvalue time in jiffies to next SIGALRM send to this process + &idummy, // starttime jiffies the process startet after system boot + &task.vsize, // vsize in bytes + &task.rss, // rss (number of pages in real memory) + dummy, // rlim limit in bytes for rss - &idummy, // itrealvalue time in jiffies to next SIGALRM send to this process - &idummy, // starttime jiffies the process startet after system boot - &task.vsize, // vsize in bytes - &task.rss, // rss (number of pages in real memory) - dummy, // rlim limit in bytes for rss + dummy, // startcode + dummy, // endcode + &idummy, // startstack + dummy, // kstkesp value of esp (stack pointer) + dummy, // kstkeip value of EIP (instruction pointer) - dummy, // startcode - dummy, // endcode - &idummy, // startstack - dummy, // kstkesp value of esp (stack pointer) - dummy, // kstkeip value of EIP (instruction pointer) + dummy, // signal. bitmap of pending signals + dummy, // blocked: bitmap of blocked signals + dummy, // sigignore: bitmap of ignored signals + dummy, // sigcatch: bitmap of catched signals + dummy, // wchan - dummy, // signal. bitmap of pending signals - dummy, // blocked: bitmap of blocked signals - dummy, // sigignore: bitmap of ignored signals - dummy, // sigcatch: bitmap of catched signals - dummy, // wchan + dummy, // nswap + dummy, // cnswap + dummy, // exit_signal + &idummy, // CPU number last executed on + dummy, - dummy, // nswap - dummy, // cnswap - dummy, // exit_signal - &idummy, // CPU number last executed on - dummy, + dummy + ); - dummy - ); + task.old_time = task.time; + task.time = stime + utime; + task.time_percentage = 0; + task.rss *= pagesize; - task.old_time = task.time; - task.time = stime + utime; - task.time_percentage = 0; - task.rss *= pagesize; + task.uid = status.st_uid; + passwdp = getpwuid(task.uid); + if(passwdp != NULL && passwdp->pw_name != NULL) + g_strlcpy(task.uname, passwdp->pw_name, sizeof(task.uname)); - task.uid = status.st_uid; - 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'; + get_cmdline(pid, task.name, sizeof(task.name), task.fullname, sizeof(task.fullname)); return task; } diff --git a/src/types.h b/src/types.h index 92fec44..56e617e 100644 --- a/src/types.h +++ b/src/types.h @@ -32,6 +32,7 @@ struct task gint uid; gchar uname[64]; gchar name[64]; + gchar fullname[255]; gchar state[16]; gint vsize; gint rss;