1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2025-02-05 05:28:32 +00:00

Merge pull request #140 from marcpayne/basename

Support for basenames (executable names)
This commit is contained in:
Brenden Matthews 2015-11-07 09:28:23 -08:00
commit dccbb13d9f
4 changed files with 58 additions and 64 deletions

View File

@ -1849,9 +1849,21 @@
</command>
<option>(process)</option>
</term>
<listitem>if PROCESS is running, display everything
$if_running and the matching $endif. This uses the
``pidof'' command, so the -x switch is also supported.
<listitem>If PROCESS is running, display everything
between $if_running and the corresponding $else or $endif.
Note that PROCESS may be either a full command line with
arguments (without the directory prefix), or simply the name
of an executable. For example, either of the following will
be true if there is a running process with the command line
<command>/usr/bin/conky -u 5</command>:
<simplelist>
<member>
<command>${if_running conky -u 5}</command> or
<command>${if_running conky}</command>
</member>
</simplelist>
It is important not to include trailing spaces. For example,
<command>${if_running conky }</command> will be false.
<para /></listitem>
</varlistentry>
<varlistentry>

View File

@ -2628,6 +2628,7 @@ static void process_parse_stat(struct process *process)
{
char line[BUFFER_LEN] = { 0 }, filename[BUFFER_LEN], procname[BUFFER_LEN];
char cmdline[BUFFER_LEN] = { 0 }, cmdline_filename[BUFFER_LEN], cmdline_procname[BUFFER_LEN];
char basename[BUFFER_LEN] = { 0 };
char tmpstr[BUFFER_LEN] = { 0 };
char state[4];
int ps, cmdline_ps;
@ -2675,36 +2676,39 @@ static void process_parse_stat(struct process *process)
return;
}
/* Some processes have null-separated arguments, let's fix it */
for(int i = 0; i < endl; i++)
if (cmdline[i] == 0)
/* Some processes have null-separated arguments (see proc(5)); let's fix it */
int i = endl;
while (i && cmdline[i-1] == 0) {
/* Skip past any trailing null characters */
--i;
}
while (i--) {
/* Replace null character between arguments with a space */
if (cmdline[i] == 0) {
cmdline[i] = ' ';
}
}
cmdline[endl] = 0;
/* We want to transform for example "/usr/bin/python program.py" to "python program.py"
* 1. search for first space
* 2. search for last / before first space
* 3. copy string from it's position */
char * space_ptr = strchr(cmdline, ' ');
if (space_ptr == NULL)
{
* 3. copy string from its position
*/
char *space_ptr = strchr(cmdline, ' ');
if (space_ptr == NULL) {
strcpy(tmpstr, cmdline);
}
else
{
} else {
long int space_pos = space_ptr - cmdline;
strncpy(tmpstr, cmdline, space_pos);
tmpstr[space_pos] = 0;
}
char * slash_ptr = strrchr(tmpstr, '/');
if (slash_ptr == NULL )
{
char *slash_ptr = strrchr(tmpstr, '/');
if (slash_ptr == NULL) {
strncpy(cmdline_procname, cmdline, BUFFER_LEN);
}
else
{
} else {
long int slash_pos = slash_ptr - tmpstr;
strncpy(cmdline_procname, cmdline + slash_pos + 1, BUFFER_LEN - slash_pos);
cmdline_procname[BUFFER_LEN - slash_pos] = 0;
@ -2713,15 +2717,16 @@ static void process_parse_stat(struct process *process)
/* Extract cpu times from data in /proc filesystem */
lparen = strchr(line, '(');
rparen = strrchr(line, ')');
if(!lparen || !rparen || rparen < lparen)
if (!lparen || !rparen || rparen < lparen)
return; // this should not happen
rc = MIN((unsigned)(rparen - lparen - 1), sizeof(procname) - 1);
strncpy(procname, lparen + 1, rc);
procname[rc] = '\0';
strncpy(basename, procname, strlen(procname) + 1);
if (strlen(procname) < strlen(cmdline_procname))
strncpy(procname, cmdline_procname, strlen(cmdline_procname)+1);
strncpy(procname, cmdline_procname, strlen(cmdline_procname) + 1);
rc = sscanf(rparen + 1, "%3s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %lu "
"%lu %*s %*s %*s %d %*s %*s %*s %llu %llu", state, &process->user_time,
@ -2731,43 +2736,13 @@ static void process_parse_stat(struct process *process)
return;
}
if(state[0]=='R')
if (state[0] == 'R')
++ info.run_procs;
/* remove any "kdeinit: " */
if (procname == strstr(procname, "kdeinit")) {
snprintf(filename, sizeof(filename), PROCFS_CMDLINE_TEMPLATE,
process->pid);
ps = open(filename, O_RDONLY);
if (ps < 0) {
/* The process must have finished in the last few jiffies! */
return;
}
endl = read(ps, line, BUFFER_LEN - 1);
close(ps);
if(endl < 0)
return;
line[endl] = 0;
/* account for "kdeinit: " */
if ((char *) line == strstr(line, "kdeinit: ")) {
r = ((char *) line) + 9;
} else {
r = (char *) line;
}
q = procname;
/* stop at space */
while (*r && *r != ' ') {
*q++ = *r++;
}
*q = 0;
}
free_and_zero(process->name);
free_and_zero(process->basename);
process->name = strndup(procname, text_buffer_size.get(*::state));
process->basename = strndup(basename, text_buffer_size.get(*::state));
process->rss *= getpagesize();
process->total_cpu_time = process->user_time + process->kernel_time;

View File

@ -32,7 +32,6 @@
#include "prioqueue.h"
#include "top.h"
#include "logging.h"
#include <string>
/* hash table size - always a power of 2 */
#define HTABSIZE 256
@ -117,6 +116,7 @@ void free_all_processes(void)
while (pr) {
next = pr->next;
free_and_zero(pr->name);
free_and_zero(pr->basename);
free(pr);
pr = next;
}
@ -131,7 +131,10 @@ struct process *get_process_by_name(const char *name)
struct process *p = first_process;
while (p) {
if (p->name && !strcmp(p->name, name))
/* Try matching against the full command line first. If that fails,
* fall back to the basename.
*/
if ((p->name && !strcmp(p->name, name)) || (p->basename && !strcmp(p->basename, name)))
return p;
p = p->next;
}
@ -165,6 +168,7 @@ static struct process *new_process(pid_t pid)
p->pid = pid;
p->name = 0;
p->basename = 0;
p->amount = 0;
p->user_time = 0;
p->total = 0;
@ -230,6 +234,7 @@ static void delete_process(struct process *p)
first_process = p->next;
free_and_zero(p->name);
free_and_zero(p->basename);
/* remove the process from the hash table */
unhash_process(p);
free(p);
@ -481,7 +486,7 @@ struct top_data {
static conky::range_config_setting<unsigned int> top_name_width("top_name_width", 0,
std::numeric_limits<unsigned int>::max(), 15, true);
static conky::simple_config_setting<bool> top_name_verbose("top_name_verbose", false, false);
static conky::simple_config_setting<bool> top_name_verbose("top_name_verbose", false, true);
static void print_top_name(struct text_object *obj, char *p, int p_max_size)
{
@ -491,13 +496,14 @@ static void print_top_name(struct text_object *obj, char *p, int p_max_size)
if (!td || !td->list || !td->list[td->num])
return;
std::string top_name = td->list[td->num]->name;
if (!top_name_verbose.get(*state)) {
top_name = top_name.substr(0, top_name.find_first_of(' '));
}
width = MIN(p_max_size, (int)top_name_width.get(*state) + 1);
snprintf(p, width + 1, "%-*s", width, top_name.c_str());
if (top_name_verbose.get(*state)) {
/* print the full command line */
snprintf(p, width + 1, "%-*s", width, td->list[td->num]->name);
} else {
/* print only the basename (i.e. executable name) */
snprintf(p, width + 1, "%-*s", width, td->list[td->num]->basename);
}
}
static void print_top_mem(struct text_object *obj, char *p, int p_max_size)

View File

@ -87,6 +87,7 @@ struct process {
pid_t pid;
char *name;
char *basename;
uid_t uid;
float amount;
// User and kernel times are in hundredths of seconds