1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2025-01-11 18:38:45 +00:00

exec: convert to generic object payload

This commit is contained in:
Phil Sutter 2009-10-07 00:09:14 +02:00
parent 0dc60481cf
commit b74e0494de
2 changed files with 110 additions and 64 deletions

View File

@ -37,6 +37,15 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
struct execi_data {
double last_update;
float interval;
char *cmd;
char *buffer;
double data;
timed_thread *p_timed_thread;
};
/* FIXME: this will probably not work, since the variable is being reused /* FIXME: this will probably not work, since the variable is being reused
* between different text objects. So when a process really hangs, it's PID * between different text objects. So when a process really hangs, it's PID
* will be overwritten at the next iteration. */ * will be overwritten at the next iteration. */
@ -160,10 +169,11 @@ static void *threaded_exec(void *arg)
{ {
char *buff, *p2; char *buff, *p2;
struct text_object *obj = arg; struct text_object *obj = arg;
struct execi_data *ed = obj->data.opaque;
while (1) { while (1) {
buff = malloc(text_buffer_size); buff = malloc(text_buffer_size);
read_exec(obj->data.execi.cmd, buff, text_buffer_size); read_exec(ed->cmd, buff, text_buffer_size);
p2 = buff; p2 = buff;
while (*p2) { while (*p2) {
if (*p2 == '\001') { if (*p2 == '\001') {
@ -171,24 +181,24 @@ static void *threaded_exec(void *arg)
} }
p2++; p2++;
} }
timed_thread_lock(obj->data.execi.p_timed_thread); timed_thread_lock(ed->p_timed_thread);
if (obj->data.execi.buffer) if (ed->buffer)
free(obj->data.execi.buffer); free(ed->buffer);
obj->data.execi.buffer = buff; ed->buffer = buff;
timed_thread_unlock(obj->data.execi.p_timed_thread); timed_thread_unlock(ed->p_timed_thread);
if (timed_thread_test(obj->data.execi.p_timed_thread, 0)) { if (timed_thread_test(ed->p_timed_thread, 0)) {
timed_thread_exit(obj->data.execi.p_timed_thread); timed_thread_exit(ed->p_timed_thread);
} }
} }
/* never reached */ /* never reached */
} }
/* check the execi fields and return true if the given interval has passed */ /* check the execi fields and return true if the given interval has passed */
static int time_to_update(struct text_object *obj) static int time_to_update(struct execi_data *ed)
{ {
if (!obj->data.execi.interval) if (!ed->interval)
return 0; return 0;
if (current_update_time - obj->data.execi.last_update >= obj->data.execi.interval) if (current_update_time - ed->last_update >= ed->interval)
return 1; return 1;
return 0; return 0;
} }
@ -209,13 +219,19 @@ void scan_pre_exec_arg(struct text_object *obj, const char *arg)
void scan_execi_arg(struct text_object *obj, const char *arg) void scan_execi_arg(struct text_object *obj, const char *arg)
{ {
struct execi_data *ed;
int n; int n;
if (sscanf(arg, "%f %n", &obj->data.execi.interval, &n) <= 0) { ed = malloc(sizeof(struct execi_data));
memset(ed, 0, sizeof(struct execi_data));
if (sscanf(arg, "%f %n", &ed->interval, &n) <= 0) {
NORM_ERR("${execi* <interval> command}"); NORM_ERR("${execi* <interval> command}");
free(ed);
return; return;
} }
obj->data.execi.cmd = strndup(arg + n, text_buffer_size); ed->cmd = strndup(arg + n, text_buffer_size);
obj->data.opaque = ed;
} }
void print_exec(struct text_object *obj, char *p, int p_max_size) void print_exec(struct text_object *obj, char *p, int p_max_size)
@ -241,44 +257,53 @@ void print_execp(struct text_object *obj, char *p, int p_max_size)
void print_execi(struct text_object *obj, char *p, int p_max_size) void print_execi(struct text_object *obj, char *p, int p_max_size)
{ {
if (time_to_update(obj)) { struct execi_data *ed = obj->data.opaque;
if (!obj->data.execi.buffer)
obj->data.execi.buffer = malloc(text_buffer_size); if (!ed)
read_exec(obj->data.execi.cmd, obj->data.execi.buffer, text_buffer_size); return;
obj->data.execi.last_update = current_update_time;
if (time_to_update(ed)) {
if (!ed->buffer)
ed->buffer = malloc(text_buffer_size);
read_exec(ed->cmd, ed->buffer, text_buffer_size);
ed->last_update = current_update_time;
} }
snprintf(p, p_max_size, "%s", obj->data.execi.buffer); snprintf(p, p_max_size, "%s", ed->buffer);
} }
void print_execpi(struct text_object *obj, char *p) void print_execpi(struct text_object *obj, char *p)
{ {
struct execi_data *ed = obj->data.opaque;
struct text_object subroot; struct text_object subroot;
struct information *tmp_info; struct information *tmp_info;
if (!ed)
return;
tmp_info = malloc(sizeof(struct information)); tmp_info = malloc(sizeof(struct information));
memcpy(tmp_info, &info, sizeof(struct information)); memcpy(tmp_info, &info, sizeof(struct information));
if (!time_to_update(obj)) { if (!time_to_update(ed)) {
parse_conky_vars(&subroot, obj->data.execi.buffer, p, tmp_info); parse_conky_vars(&subroot, ed->buffer, p, tmp_info);
} else { } else {
char *output; char *output;
int length; int length;
FILE *fp = pid_popen(obj->data.execi.cmd, "r", &childpid); FILE *fp = pid_popen(ed->cmd, "r", &childpid);
if (!obj->data.execi.buffer) if (!ed->buffer)
obj->data.execi.buffer = malloc(text_buffer_size); ed->buffer = malloc(text_buffer_size);
length = fread(obj->data.execi.buffer, 1, text_buffer_size, fp); length = fread(ed->buffer, 1, text_buffer_size, fp);
pclose(fp); pclose(fp);
output = obj->data.execi.buffer; output = ed->buffer;
output[length] = '\0'; output[length] = '\0';
if (length > 0 && output[length - 1] == '\n') { if (length > 0 && output[length - 1] == '\n') {
output[length - 1] = '\0'; output[length - 1] = '\0';
} }
parse_conky_vars(&subroot, obj->data.execi.buffer, p, tmp_info); parse_conky_vars(&subroot, ed->buffer, p, tmp_info);
obj->data.execi.last_update = current_update_time; ed->last_update = current_update_time;
} }
free_text_objects(&subroot, 1); free_text_objects(&subroot, 1);
free(tmp_info); free(tmp_info);
@ -286,24 +311,28 @@ void print_execpi(struct text_object *obj, char *p)
void print_texeci(struct text_object *obj, char *p, int p_max_size) void print_texeci(struct text_object *obj, char *p, int p_max_size)
{ {
if (!obj->data.execi.p_timed_thread) { struct execi_data *ed = obj->data.opaque;
obj->data.execi.p_timed_thread =
timed_thread_create(&threaded_exec, if (!ed)
(void *) obj, obj->data.execi.interval * 1000000); return;
if (!obj->data.execi.p_timed_thread) {
if (!ed->p_timed_thread) {
ed->p_timed_thread = timed_thread_create(&threaded_exec,
(void *) obj, ed->interval * 1000000);
if (!ed->p_timed_thread) {
NORM_ERR("Error creating texeci timed thread"); NORM_ERR("Error creating texeci timed thread");
} }
/* /*
* note that we don't register this thread with the * note that we don't register this thread with the
* timed_thread list, because we destroy it manually * timed_thread list, because we destroy it manually
*/ */
if (timed_thread_run(obj->data.execi.p_timed_thread)) { if (timed_thread_run(ed->p_timed_thread)) {
NORM_ERR("Error running texeci timed thread"); NORM_ERR("Error running texeci timed thread");
} }
} else { } else {
timed_thread_lock(obj->data.execi.p_timed_thread); timed_thread_lock(ed->p_timed_thread);
snprintf(p, p_max_size, "%s", obj->data.execi.buffer); snprintf(p, p_max_size, "%s", ed->buffer);
timed_thread_unlock(obj->data.execi.p_timed_thread); timed_thread_unlock(ed->p_timed_thread);
} }
} }
@ -326,7 +355,13 @@ void print_execgraph(struct text_object *obj, char *p, int p_max_size)
char showaslog = FALSE; char showaslog = FALSE;
char tempgrad = FALSE; char tempgrad = FALSE;
double barnum; double barnum;
char *cmd = obj->data.execi.cmd; struct execi_data *ed = obj->data.opaque;
char *cmd;
if (!ed)
return;
cmd = ed->cmd;
if (strstr(cmd, " "TEMPGRAD) && strlen(cmd) > strlen(" "TEMPGRAD)) { if (strstr(cmd, " "TEMPGRAD) && strlen(cmd) > strlen(" "TEMPGRAD)) {
tempgrad = TRUE; tempgrad = TRUE;
@ -347,11 +382,16 @@ void print_execgraph(struct text_object *obj, char *p, int p_max_size)
void print_execigraph(struct text_object *obj, char *p, int p_max_size) void print_execigraph(struct text_object *obj, char *p, int p_max_size)
{ {
if (time_to_update(obj)) { struct execi_data *ed = obj->data.opaque;
if (!ed)
return;
if (time_to_update(ed)) {
double barnum; double barnum;
char showaslog = FALSE; char showaslog = FALSE;
char tempgrad = FALSE; char tempgrad = FALSE;
char *cmd = obj->data.execi.cmd; char *cmd = ed->cmd;
if (strstr(cmd, " "TEMPGRAD) && strlen(cmd) > strlen(" "TEMPGRAD)) { if (strstr(cmd, " "TEMPGRAD) && strlen(cmd) > strlen(" "TEMPGRAD)) {
tempgrad = TRUE; tempgrad = TRUE;
@ -369,23 +409,28 @@ void print_execigraph(struct text_object *obj, char *p, int p_max_size)
if (barnum >= 0.0) { if (barnum >= 0.0) {
obj->f = barnum; obj->f = barnum;
} }
obj->data.execi.last_update = current_update_time; ed->last_update = current_update_time;
} }
new_graph(p, obj->a, obj->b, obj->c, obj->d, (int) (obj->f), 100, 1, obj->char_a, obj->char_b); new_graph(p, obj->a, obj->b, obj->c, obj->d, (int) (obj->f), 100, 1, obj->char_a, obj->char_b);
} }
void print_execigauge(struct text_object *obj, char *p, int p_max_size) void print_execigauge(struct text_object *obj, char *p, int p_max_size)
{ {
if (time_to_update(obj)) { struct execi_data *ed = obj->data.opaque;
if (!ed)
return;
if (time_to_update(ed)) {
double barnum; double barnum;
read_exec(obj->data.execi.cmd, p, p_max_size); read_exec(ed->cmd, p, p_max_size);
barnum = get_barnum(p); barnum = get_barnum(p);
if (barnum >= 0.0) { if (barnum >= 0.0) {
obj->f = 255 * barnum / 100.0; obj->f = 255 * barnum / 100.0;
} }
obj->data.execi.last_update = current_update_time; ed->last_update = current_update_time;
} }
new_gauge(p, obj->a, obj->b, round_to_int(obj->f)); new_gauge(p, obj->a, obj->b, round_to_int(obj->f));
} }
@ -413,16 +458,20 @@ void print_execbar(struct text_object *obj, char *p, int p_max_size)
void print_execibar(struct text_object *obj, char *p, int p_max_size) void print_execibar(struct text_object *obj, char *p, int p_max_size)
{ {
struct execi_data *ed = obj->data.opaque;
double barnum; double barnum;
if (time_to_update(obj)) { if (!ed)
read_exec(obj->data.execi.cmd, p, p_max_size); return;
if (time_to_update(ed)) {
read_exec(ed->cmd, p, p_max_size);
barnum = get_barnum(p); barnum = get_barnum(p);
if (barnum >= 0.0) { if (barnum >= 0.0) {
obj->f = barnum; obj->f = barnum;
} }
obj->data.execi.last_update = current_update_time; ed->last_update = current_update_time;
} }
#ifdef X11 #ifdef X11
if(output_methods & TO_X) { if(output_methods & TO_X) {
@ -445,11 +494,17 @@ void free_exec(struct text_object *obj)
void free_execi(struct text_object *obj) void free_execi(struct text_object *obj)
{ {
if (obj->data.execi.p_timed_thread) struct execi_data *ed = obj->data.opaque;
timed_thread_destroy(obj->data.execi.p_timed_thread, &obj->data.execi.p_timed_thread);
if (obj->data.execi.cmd) if (!ed)
free(obj->data.execi.cmd); return;
if (obj->data.execi.buffer)
free(obj->data.execi.buffer); if (ed->p_timed_thread)
memset(&obj->data.execi, 0, sizeof(obj->data.execi)); timed_thread_destroy(ed->p_timed_thread, &ed->p_timed_thread);
if (ed->cmd)
free(ed->cmd);
if (ed->buffer)
free(ed->buffer);
free(obj->data.opaque);
obj->data.opaque = NULL;
} }

View File

@ -457,15 +457,6 @@ struct text_object {
char *str; char *str;
} ifblock; } ifblock;
struct {
double last_update;
float interval;
char *cmd;
char *buffer;
double data;
timed_thread *p_timed_thread;
} execi; /* 5 */
struct { struct {
int a, b; int a, b;
} pair; /* 2 */ } pair; /* 2 */