From 2d10c4c08d9e23217b7c112e2f0a903981a30094 Mon Sep 17 00:00:00 2001 From: Brenden Matthews Date: Fri, 28 Sep 2007 20:16:16 +0000 Subject: [PATCH] * Small fix for $ibm_volume (thanks Kapil Hari Paranjape) * Patch so $tail can read from a fifo file descriptor (thanks Ben Kibbey) git-svn-id: https://conky.svn.sourceforge.net/svnroot/conky/trunk/conky1@966 7f574dfc-610e-0410-a909-a81674777703 --- AUTHORS | 6 ++ ChangeLog | 4 ++ doc/conkyrc.sample | 1 - src/conky.c | 145 +++++++++++++++++++++++++++++++++++++++++++-- src/linux.c | 75 ++++++++++++----------- 5 files changed, 188 insertions(+), 43 deletions(-) diff --git a/AUTHORS b/AUTHORS index c8adb670..8bcf3792 100644 --- a/AUTHORS +++ b/AUTHORS @@ -19,6 +19,9 @@ affinity akash battery_percent and battery_bar +Ben Kibbey + $tail fifo patch + Blondak diskio read & write patch @@ -139,6 +142,9 @@ J Some cleaning and commenting apparently :) SIGHUP config file reload +Kapil Hari Paranjape + ibm_volume patch + killfire fs_used_perc and fs_bar_free patch diff --git a/ChangeLog b/ChangeLog index c64d9dde..977734d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ # $Id$ +2007-09-28 + * Small fix for $ibm_volume (thanks Kapil Hari Paranjape) + * Patch so $tail can read from a fifo file descriptor (thanks Ben Kibbey) + 2007-09-01 * Improved performance slightly * Added 'music_player_interval' config option to specify an update interval for diff --git a/doc/conkyrc.sample b/doc/conkyrc.sample index d4f2f976..bb1d3da3 100644 --- a/doc/conkyrc.sample +++ b/doc/conkyrc.sample @@ -170,7 +170,6 @@ ${color}Mem usage ${color #ddaa00} ${top_mem name 1} ${top_mem pid 1} ${top_mem cpu 1} ${top_mem mem 1} ${color lightgrey} ${top_mem name 2} ${top_mem pid 2} ${top_mem cpu 2} ${top_mem mem 2} ${color lightgrey} ${top_mem name 3} ${top_mem pid 3} ${top_mem cpu 3} ${top_mem mem 3} -${tail /var/log/Xorg.0.log 3 30} $stippled_hr ${color #ddaa00}Port(s)${alignr}#Connections $color Inbound: ${tcp_portmon 1 32767 count} Outbound: ${tcp_portmon 32768 61000 count}${alignr}ALL: ${tcp_portmon 1 65535 count} diff --git a/src/conky.c b/src/conky.c index f198fbac..208c2c4a 100644 --- a/src/conky.c +++ b/src/conky.c @@ -55,6 +55,7 @@ #include #include #include +#include #ifdef HAVE_ICONV #include @@ -1246,6 +1247,9 @@ struct text_object { double last_update; float interval; char *buffer; + /* If not -1, a file descriptor to read from when + * logfile is a FIFO. */ + int fd; } tail; struct { @@ -2716,6 +2720,7 @@ static struct text_object *construct_text_object(const char *s, const char *arg, END OBJ(tail, 0) char buf[64]; int n1, n2; + struct stat st; if (!arg) { ERR("tail needs arguments"); obj->type = OBJ_text; @@ -2728,15 +2733,34 @@ static struct text_object *construct_text_object(const char *s, const char *arg, return NULL; } else { FILE *fp = NULL; - fp = fopen(buf, "r"); - if (fp) { + int fd; + + obj->data.tail.fd = -1; + + if (stat(buf, &st) == 0) { + if (S_ISFIFO(st.st_mode)) { + fd = open(buf, O_RDONLY|O_NONBLOCK); + + if (fd == -1) + CRIT_ERR("tail logfile does not exist, or you do not have correct permissions"); + + obj->data.tail.fd = fd; + + } + else + fp = fopen(buf, "r"); + } + + if (fp || obj->data.tail.fd != -1) { obj->data.tail.logfile = malloc(text_buffer_size); strcpy(obj->data.tail.logfile, buf); obj->data.tail.wantedlines = n1; obj->data.tail.interval = update_interval * 2; - fclose(fp); + + if (obj->data.tail.fd == -1) + fclose(fp); } else { //fclose (fp); CRIT_ERR("tail logfile does not exist, or you do not have correct permissions"); @@ -2753,14 +2777,32 @@ static struct text_object *construct_text_object(const char *s, const char *arg, return NULL; } else { FILE *fp; - fp = fopen(buf, "r"); - if (fp != NULL) { + int fd; + + obj->data.tail.fd = -1; + + if (stat(buf, &st) == 0) { + if (S_ISFIFO(st.st_mode)) { + fd = open(buf, O_RDONLY|O_NONBLOCK); + + if (fd == -1) + CRIT_ERR("tail logfile does not exist, or you do not have correct permissions"); + + obj->data.tail.fd = fd; + } + else + fp = fopen(buf, "r"); + } + + if (fp || obj->data.tail.fd != -1) { obj->data.tail.logfile = malloc(text_buffer_size); strcpy(obj->data.tail.logfile, buf); obj->data.tail.wantedlines = n1; obj->data.tail.interval = n2; - fclose(fp); + + if (obj->data.tail.fd == -1) + fclose(fp); } else { //fclose (fp); CRIT_ERR("tail logfile does not exist, or you do not have correct permissions"); @@ -3522,6 +3564,89 @@ void parse_conky_vars(char * text, char * p, struct information *cur) { free(object_list); } +/* + * Allows reading from a FIFO (i.e., /dev/xconsole). The file descriptor is + * set to non-blocking which makes this possible. + * + * FIXME + * Since lseek cannot seek a file descriptor long lines will break. + */ +static void tail_pipe(struct text_object *obj, char *dst, size_t dst_size) +{ +#define TAIL_PIPE_BUFSIZE 4096 + int lines = 0; + int line_len = 0; + int last_line = 0; + int fd = obj->data.tail.fd; + + while (1) { + char buf[TAIL_PIPE_BUFSIZE]; + ssize_t len = read(fd, buf, sizeof(buf)); + int i; + + if (len == -1) { + if (errno != EAGAIN) { + strcpy(obj->data.tail.buffer, "Logfile Read Error"); + snprintf(dst, dst_size, "Logfile Read Error"); + } + + break; + } + else if (len == 0) { + strcpy(obj->data.tail.buffer, "Logfile Empty"); + snprintf(dst, dst_size, "Logfile Empty"); + break; + } + + for (line_len = 0, i = 0; i < len; i++) { + int pos = 0; + char *p; + + if (buf[i] == '\n') { + lines++; + + if (obj->data.tail.readlines > 0) { + int n; + int olines = 0; + int first_line = 0; + + for (n = 0; obj->data.tail.buffer[n]; n++) { + if (obj->data.tail.buffer[n] == '\n') { + if (!first_line) + first_line = n+1; + + if (++olines < obj->data.tail.wantedlines) { + pos = n+1; + continue; + } + + n++; + p = obj->data.tail.buffer + first_line; + pos = n - first_line; + memmove(obj->data.tail.buffer, obj->data.tail.buffer + first_line, strlen(p)); + obj->data.tail.buffer[pos] = 0; + break; + } + } + } + + p = buf + last_line; + line_len++; + memcpy(&(obj->data.tail.buffer[pos]), p, line_len); + obj->data.tail.buffer[pos + line_len] = 0; + last_line = i+1; + line_len = 0; + obj->data.tail.readlines = lines; + continue; + } + + line_len++; + } + } + + snprintf(dst, dst_size, "%s", obj->data.tail.buffer); +} + static void generate_text_internal(char *p, int p_max_size, struct text_object *objs, unsigned int object_count, struct information *cur) { unsigned int i; @@ -5156,7 +5281,14 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object * FILE *fp; long nl=0, bsize; int iter; + + if (obj->data.tail.fd != -1) { + tail_pipe(obj, p, p_max_size); + goto head; + } + fp = fopen(obj->data.tail.logfile, "rt"); + if (fp == NULL) { /* Send one message, but do not consistently spam on * missing logfiles. */ @@ -5212,6 +5344,7 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object * //parse_conky_vars(obj->data.tail.buffer, p, cur); } +head: OBJ(head) { if (current_update_time -obj->data.tail.last_update < obj->data.tail.interval) { snprintf(p, p_max_size, "%s", obj->data.tail.buffer); diff --git a/src/linux.c b/src/linux.c index f158bfba..fbe5043b 100644 --- a/src/linux.c +++ b/src/linux.c @@ -1894,10 +1894,10 @@ Peter Tarjan (ptarjan@citromail.hu) void get_ibm_acpi_volume( char * p_client_buffer, size_t client_buffer_size ) { -/* get volume (0-14) on IBM/Lenovo laptops running the ibm acpi. - "Volume" here is none of the mixer volumes, but a "master of masters" - volume adjusted by the IBM volume keys. - /proc/acpi/ibm/fan looks like this (4 lines): + /* get volume (0-14) on IBM/Lenovo laptops running the ibm acpi. + "Volume" here is none of the mixer volumes, but a "master of masters" + volume adjusted by the IBM volume keys. + /proc/acpi/ibm/fan looks like this (4 lines): level: 4 mute: off commands: up, down, mute @@ -1905,44 +1905,47 @@ commands: level ( is 0-15) Peter Tarjan (ptarjan@citromail.hu) */ - if ( !p_client_buffer || client_buffer_size <= 0 ) - return; + if ( !p_client_buffer || client_buffer_size <= 0 ) + return; - FILE *fp; + FILE *fp; - char volume[128]; - snprintf(volume, 127, "%s/volume",IBM_ACPI_DIR); - unsigned int vol=-1; - char mute[3]=""; + char volume[128]; + snprintf(volume, 127, "%s/volume",IBM_ACPI_DIR); + unsigned int vol=-1; + char mute[3]=""; - fp = fopen(volume, "r"); - if (fp != NULL) - { - while (!feof(fp)) - { - char line[256]; - if (fgets(line, 255, fp) == NULL) break; - if (sscanf(line, "level: %d", &vol)) continue; - if (sscanf(line, "mute: %s", mute)) break; + fp = fopen(volume, "r"); + if (fp != NULL) { + while (!feof(fp)) { + char line[256]; + unsigned int read_vol = -1; + if (fgets(line, 255, fp) == NULL) break; + if (sscanf(line, "level: %d", &read_vol)) { + vol = read_vol; + continue; + } + if (sscanf(line, "level: %d", &vol)) continue; + if (sscanf(line, "mute: %s", mute)) break; + } + } + else + { + CRIT_ERR("can't open '%s': %s\nYou are not using the IBM ACPI. Remove ibm* from your Conky config file.", volume, strerror(errno)); } - } - else - { - CRIT_ERR("can't open '%s': %s\nYou are not using the IBM ACPI. Remove ibm* from your Conky config file.", volume, strerror(errno)); - } - fclose(fp); + fclose(fp); - if (strcmp(mute, "on")==0) - { - snprintf( p_client_buffer, client_buffer_size, "%s", "mute" ); - return; - } - else - { - snprintf( p_client_buffer, client_buffer_size, "%d", vol ); - return; - } + if (strcmp(mute, "on")==0) + { + snprintf( p_client_buffer, client_buffer_size, "%s", "mute" ); + return; + } + else + { + snprintf( p_client_buffer, client_buffer_size, "%d", vol ); + return; + } }