* Small fix for $ibm_volume (thanks Kapil Hari Paranjape)
authorBrenden Matthews <brenden1@rty.ca>
Fri, 28 Sep 2007 20:16:16 +0000 (20:16 +0000)
committerBrenden Matthews <brenden1@rty.ca>
Fri, 28 Sep 2007 20:16:16 +0000 (20:16 +0000)
    * 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
ChangeLog
doc/conkyrc.sample
src/conky.c
src/linux.c

diff --git a/AUTHORS b/AUTHORS
index c8adb67..8bcf379 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -19,6 +19,9 @@ affinity <affy at users dot sourceforge dot net>
 akash <akash at users dot sourceforge dot net>
   battery_percent and battery_bar
 
+Ben Kibbey <benkibbey at users dot sourceforge dot net>
+  $tail fifo patch
+
 Blondak <blondak_nesercz at users dot sourceforge dot net>
   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
 
index c64d9dd..977734d 100644 (file)
--- 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
index d4f2f97..bb1d3da 100644 (file)
@@ -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}
index f198fba..208c2c4 100644 (file)
@@ -55,6 +55,7 @@
 #include <sys/stat.h>
 #include <netinet/in.h>
 #include <netdb.h>
+#include <fcntl.h>
 
 #ifdef HAVE_ICONV
 #include <iconv.h>
@@ -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);
index f158bfb..fbe5043 100644 (file)
@@ -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 <level> (<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))
+       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
        {
-           char line[256];
-           if (fgets(line, 255, fp) == NULL) break;
-           if (sscanf(line, "level: %d", &vol)) continue;
-           if (sscanf(line, "mute: %s", mute)) break;
+               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;
+       }
 
 }