aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.in11
-rwxr-xr-xconfigure16
-rw-r--r--plugin_exec.c235
-rw-r--r--qprintf.c41
-rw-r--r--thread.c14
-rw-r--r--thread.h11
6 files changed, 272 insertions, 56 deletions
diff --git a/Makefile.in b/Makefile.in
index abbe2f5..f26474a 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -91,7 +91,7 @@ lcd4linux_LDADD = @DRIVERS@ @DRVLIBS@
#remove next line for liblcd4linux
lcd4linux_DEPENDENCIES = @DRIVERS@
-lcd4linux_SOURCES = lcd4linux.c cfg.c cfg.h debug.c debug.h drv.c drv.h evaluator.c evaluator.h hash.c hash.h layout.c layout.h lock.c lock.h pid.c pid.h timer.c timer.h thread.c thread.h udelay.c udelay.h qprintf.c qprintf.h widget.c widget.h widget_text.c widget_text.h widget_bar.c widget_bar.h widget_icon.c widget_icon.h plugin.c plugin.h plugin_math.c plugin_string.c plugin_cfg.c plugin_uname.c plugin_loadavg.c plugin_proc_stat.c plugin_cpuinfo.c plugin_meminfo.c plugin_netdev.c plugin_ppp.c plugin_dvb.c plugin_apm.c plugin_i2c_sensors.c plugin_imon.c plugin_exec.c plugin_xmms.c plugin_mysql.c plugin_seti.c
+lcd4linux_SOURCES = lcd4linux.c cfg.c cfg.h debug.c debug.h drv.c drv.h evaluator.c evaluator.h hash.c hash.h layout.c layout.h lock.c lock.h pid.c pid.h timer.c timer.h thread.c thread.h udelay.c udelay.h qprintf.c qprintf.h widget.c widget.h widget_text.c widget_text.h widget_bar.c widget_bar.h widget_icon.c widget_icon.h plugin.c plugin.h plugin_math.c plugin_string.c plugin_cfg.c plugin_uname.c plugin_loadavg.c plugin_proc_stat.c plugin_cpuinfo.c plugin_meminfo.c plugin_netdev.c plugin_ppp.c plugin_dvb.c plugin_apm.c plugin_i2c_sensors.c plugin_imon.c plugin_exec.c plugin_xmms.c plugin_mysql.c plugin_wireless.c plugin_seti.c
#liblcd4linux_la_DEPENDENCIES = @DRIVERS@
@@ -126,7 +126,8 @@ widget_text.o widget_bar.o widget_icon.o plugin.o plugin_math.o \
plugin_string.o plugin_cfg.o plugin_uname.o plugin_loadavg.o \
plugin_proc_stat.o plugin_cpuinfo.o plugin_meminfo.o plugin_netdev.o \
plugin_ppp.o plugin_dvb.o plugin_apm.o plugin_i2c_sensors.o \
-plugin_imon.o plugin_exec.o plugin_xmms.o plugin_mysql.o plugin_seti.o
+plugin_imon.o plugin_exec.o plugin_xmms.o plugin_mysql.o \
+plugin_wireless.o plugin_seti.o
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
@@ -155,9 +156,9 @@ DEP_FILES = .deps/BeckmannEgle.P .deps/MilfordInstruments.P \
.deps/plugin_math.P .deps/plugin_meminfo.P .deps/plugin_mysql.P \
.deps/plugin_netdev.P .deps/plugin_ppp.P .deps/plugin_proc_stat.P \
.deps/plugin_seti.P .deps/plugin_string.P .deps/plugin_uname.P \
-.deps/plugin_xmms.P .deps/qprintf.P .deps/thread.P .deps/timer.P \
-.deps/udelay.P .deps/widget.P .deps/widget_bar.P .deps/widget_icon.P \
-.deps/widget_text.P
+.deps/plugin_wireless.P .deps/plugin_xmms.P .deps/qprintf.P \
+.deps/thread.P .deps/timer.P .deps/udelay.P .deps/widget.P \
+.deps/widget_bar.P .deps/widget_icon.P .deps/widget_text.P
SOURCES = $(lcd4linux_SOURCES) $(EXTRA_lcd4linux_SOURCES)
OBJECTS = $(lcd4linux_OBJECTS)
diff --git a/configure b/configure
index 92e5143..3fb9c02 100755
--- a/configure
+++ b/configure
@@ -3966,9 +3966,12 @@ _ACEOF
# Checks for X11
-echo "$as_me:$LINENO: checking for X" >&5
+
+if test "x$ac_path_x_has_been_run" != xyes; then
+ echo "$as_me:$LINENO: checking for X" >&5
echo $ECHO_N "checking for X... $ECHO_C" >&6
+ac_path_x_has_been_run=yes
# Check whether --with-x or --without-x was given.
if test "${with_x+set}" = set; then
@@ -4061,7 +4064,7 @@ ac_x_header_dirs='
/usr/openwin/share/include'
if test "$ac_x_includes" = no; then
- # Guess where to find include files, by looking for Intrinsic.h.
+ # Guess where to find include files, by looking for a specified header file.
# First, try using that file with no special directory specified.
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
@@ -4195,10 +4198,15 @@ else
# Update the cache value to reflect the command line values.
ac_cv_have_x="have_x=yes \
ac_x_includes=$x_includes ac_x_libraries=$x_libraries"
- echo "$as_me:$LINENO: result: libraries $x_libraries, headers $x_includes" >&5
-echo "${ECHO_T}libraries $x_libraries, headers $x_includes" >&6
+ # It might be that x_includes is empty (headers are found in the
+ # standard search path. Then output the corresponding message
+ ac_out_x_includes=$x_includes
+ test "x$x_includes" = x && ac_out_x_includes="in standard search path"
+ echo "$as_me:$LINENO: result: libraries $x_libraries, headers $ac_out_x_includes" >&5
+echo "${ECHO_T}libraries $x_libraries, headers $ac_out_x_includes" >&6
fi
+fi
if test "$no_x" = yes; then
# Not all programs may use this symbol, but it does not hurt to define it.
diff --git a/plugin_exec.c b/plugin_exec.c
index 59bfb89..565ace1 100644
--- a/plugin_exec.c
+++ b/plugin_exec.c
@@ -1,4 +1,4 @@
-/* $Id: plugin_exec.c,v 1.1 2004/03/20 11:49:40 reinelt Exp $
+/* $Id: plugin_exec.c,v 1.2 2004/04/08 10:48:25 reinelt Exp $
*
* plugin for external processes
*
@@ -27,6 +27,11 @@
*
*
* $Log: plugin_exec.c,v $
+ * Revision 1.2 2004/04/08 10:48:25 reinelt
+ * finished plugin_exec
+ * modified thread handling
+ * added '%x' format to qprintf (hexadecimal)
+ *
* Revision 1.1 2004/03/20 11:49:40 reinelt
* forgot to add plugin_exec.c ...
*
@@ -46,63 +51,215 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
-
-// #include <string.h>
-// #include <ctype.h>
-// #include <errno.h>
-
-#include <sys/ipc.h>
-#include <sys/sem.h>
-#include <sys/shm.h>
+#include <string.h>
+#include <errno.h>
#include "debug.h"
#include "plugin.h"
#include "hash.h"
#include "cfg.h"
#include "thread.h"
+#include "qprintf.h"
+
+
+#define NUM_THREADS 16
+#define SHM_SIZE 256
+
+typedef struct {
+ int delay;
+ int mutex;
+ pid_t pid;
+ int shmid;
+ char *cmd;
+ char *key;
+ char *ret;
+} EXEC_THREAD;
+
+static EXEC_THREAD Thread[NUM_THREADS];
+static int max_thread = -1;
static HASH EXEC = { 0, };
-static int fatal = 0;
-static int do_exec (void)
+
+// x^0 + x^5 + x^12
+#define CRCPOLY 0x8408
+
+static unsigned short CRC (unsigned char *s)
+{
+ int i;
+ unsigned short crc;
+
+ // seed value
+ crc=0xffff;
+
+ while (*s!='\0') {
+ crc ^= *s++;
+ for (i = 0; i < 8; i++)
+ crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY : 0);
+ }
+ return crc;
+}
+
+
+static void exec_thread (void *data)
+{
+ EXEC_THREAD *Thread = (EXEC_THREAD*)data;
+ FILE *pipe;
+ char buffer[SHM_SIZE];
+ int len;
+
+ // use a safe path
+ putenv ("PATH=/usr/local/bin:/usr/bin:/bin");
+
+ // forever...
+ while (1) {
+ pipe = popen(Thread->cmd, "r");
+ if (pipe == NULL) {
+ error("exec error: could not run pipe '%s': %s", Thread->cmd, strerror(errno));
+ len = 0;
+ } else {
+ len = fread(buffer, 1, SHM_SIZE-1, pipe);
+ if (len <= 0) {
+ error("exec error: could not read from pipe '%s': %s", Thread->cmd, strerror(errno));
+ len = 0;
+ }
+ pclose(pipe);
+ }
+
+ // force trailing zero
+ buffer[len] = '\0';
+
+ // remove trailing CR/LF
+ while (len>0 && (buffer[len-1]=='\n' || buffer[len-1]=='\r')) {
+ buffer[--len]='\0';
+ }
+
+ // lock shared memory
+ mutex_lock(Thread->mutex);
+ // write data
+ strncpy(Thread->ret, buffer, SHM_SIZE);
+ // unlock shared memory
+ mutex_unlock(Thread->mutex);
+ usleep (Thread->delay);
+ }
+}
+
+
+static void destroy_exec_thread (int n)
+{
+ if (Thread[n].mutex != 0) mutex_destroy(Thread[n].mutex);
+ if (Thread[n].cmd) free (Thread[n].cmd);
+ if (Thread[n].key) free (Thread[n].key);
+ if (Thread[n].ret) shm_destroy (Thread[n].shmid, Thread[n].ret);
+
+ Thread[n].delay = 0;
+ Thread[n].mutex = 0;
+ Thread[n].pid = 0;
+ Thread[n].shmid = 0;
+ Thread[n].cmd = NULL;
+ Thread[n].key = NULL;
+ Thread[n].ret = NULL;
+}
+
+
+static int create_exec_thread (char *cmd, char *key, int delay)
{
- int age;
+ char name[10];
+
+ if (max_thread >= NUM_THREADS) {
+ error ("cannot create exec thread <%s>: thread buffer full!", cmd);
+ return -1;
+ }
+
+ max_thread++;
+ Thread[max_thread].delay = delay;
+ Thread[max_thread].mutex = mutex_create();
+ Thread[max_thread].pid = -1;
+ Thread[max_thread].cmd = strdup(cmd);
+ Thread[max_thread].key = strdup(key);
+ Thread[max_thread].ret = NULL;
+
+ // create communication buffer
+ Thread[max_thread].shmid = shm_create ((void**)&Thread[max_thread].ret, SHM_SIZE);
+
+ // catch error
+ if (Thread[max_thread].shmid < 0) {
+ error ("cannot create exec thread <%s>: shared memory allocation failed!", cmd);
+ destroy_exec_thread (max_thread--);
+ return -1;
+ }
- // if a fatal error occured, do nothing
- if (fatal != 0) return -1;
+ // create thread
+ qprintf(name, sizeof(name), "exec-%s", key);
+ Thread[max_thread].pid = thread_create (name, exec_thread, &Thread[max_thread]);
+
+ // catch error
+ if (Thread[max_thread].pid < 0) {
+ error ("cannot create exec thread <%s>: fork failed?!", cmd);
+ destroy_exec_thread (max_thread--);
+ return -1;
+ }
- // reread every 100 msec only
- age=hash_age(&EXEC, NULL, NULL);
- if (age>0 && age<=100) return 0;
return 0;
-}
+}
-static void my_junk (char *name)
+
+static int do_exec (char *cmd, char *key, int delay)
{
- int i;
+ int i, age;
+
+ age = hash_age(&EXEC, key, NULL);
- debug ("junk thread starting!");
+ if (age < 0) {
+ hash_set (&EXEC, key, "");
+ // first-time call: create thread
+ if (delay < 10) {
+ error ("exec(%s): delay %d is too short! using 10 msec", cmd, delay);
+ delay = 10;
+ }
+ if (create_exec_thread (cmd, key, 1000*delay)) {
+ return -1;
+ }
+ return 0;
+ }
+
+ // reread every 10 msec only
+ if (age > 0 && age <= 10) return 0;
- for (i=0; i<10; i++) {
- debug ("junk look %d", i);
- sleep (1);
+ // find thread
+ for (i = 0; i <= max_thread; i++) {
+ if (strcmp(key, Thread[i].key) == 0) {
+ // lock shared memory
+ mutex_lock(Thread[i].mutex);
+ // copy data
+ hash_set (&EXEC, key, Thread[i].ret);
+ // unlock shared memory
+ mutex_unlock(Thread[i].mutex);
+ return 0;
+ }
}
- debug ("junk thread done!");
+
+ error ("internal error: could not find thread exec-%s", key);
+ return -1;
}
-
-static void my_exec (RESULT *result, int argc, RESULT *argv[])
+static void my_exec (RESULT *result, RESULT *arg1, RESULT *arg2)
{
- char *key, *val;
+ char *cmd, key[5], *val;
+ int delay;
- if (do_exec()<0) {
+ cmd = R2S(arg1);
+ delay = (int)R2N(arg2);
+
+ qprintf (key, sizeof(key), "%x", CRC(cmd));
+
+ if (do_exec(cmd, key, delay) < 0) {
SetResult(&result, R_STRING, "");
return;
}
- // key=R2S(arg1);
- val=hash_get(&EXEC, key);
- if (val==NULL) val="";
+ val = hash_get(&EXEC, key);
+ if (val == NULL) val = "";
SetResult(&result, R_STRING, val);
}
@@ -110,18 +267,18 @@ static void my_exec (RESULT *result, int argc, RESULT *argv[])
int plugin_init_exec (void)
{
- int junk;
-
- AddFunction ("exec", -1, my_exec);
-
- // junk=thread_create ("Junk", my_junk);
- // debug ("junk=%d", junk);
-
+ AddFunction ("exec", 2, my_exec);
return 0;
}
void plugin_exit_exec(void)
{
+ int i;
+
+ for (i=0; i<=max_thread; i++) {
+ destroy_exec_thread(i);
+ }
+
hash_destroy(&EXEC);
}
diff --git a/qprintf.c b/qprintf.c
index 2a51782..6b923ce 100644
--- a/qprintf.c
+++ b/qprintf.c
@@ -1,4 +1,4 @@
-/* $Id: qprintf.c,v 1.1 2004/02/27 07:06:26 reinelt Exp $
+/* $Id: qprintf.c,v 1.2 2004/04/08 10:48:25 reinelt Exp $
*
* simple but quick snprintf() replacement
*
@@ -26,6 +26,11 @@
*
*
* $Log: qprintf.c,v $
+ * Revision 1.2 2004/04/08 10:48:25 reinelt
+ * finished plugin_exec
+ * modified thread handling
+ * added '%x' format to qprintf (hexadecimal)
+ *
* Revision 1.1 2004/02/27 07:06:26 reinelt
* new function 'qprintf()' (simple but quick snprintf() replacement)
*
@@ -79,6 +84,30 @@ static char *itoa(char* buffer, size_t size, int value)
}
+static char *itox(char* buffer, size_t size, unsigned int value)
+{
+ char *p;
+ int digit;
+
+ // sanity checks
+ if (buffer==NULL || size<2) return (NULL);
+
+ // p points to last char
+ p = buffer+size-1;
+
+ // set terminating zero
+ *p='\0';
+
+ do {
+ digit = value%16;
+ value = value/16;
+ *--p = (digit < 10 ? '0' : 'a'-10) + digit;
+ } while (value!=0 && p>buffer);
+
+ return p;
+}
+
+
int qprintf(char *str, size_t size, const char *format, ...) {
va_list ap;
@@ -100,6 +129,7 @@ int qprintf(char *str, size_t size, const char *format, ...) {
if (*src=='%') {
char buf[12], *s;
int d;
+ unsigned int u;
switch (*++src) {
case 's':
src++;
@@ -118,6 +148,15 @@ int qprintf(char *str, size_t size, const char *format, ...) {
*dst++ = *s++;
}
break;
+ case 'x':
+ src++;
+ u = va_arg(ap, unsigned int);
+ s = itox (buf, sizeof(buf), u);
+ while (len < size && *s != '\0') {
+ len++;
+ *dst++ = *s++;
+ }
+ break;
default:
len++;
*dst++ = '%';
diff --git a/thread.c b/thread.c
index 8e4e8e4..f59396c 100644
--- a/thread.c
+++ b/thread.c
@@ -1,4 +1,4 @@
-/* $Id: thread.c,v 1.2 2004/03/20 07:31:33 reinelt Exp $
+/* $Id: thread.c,v 1.3 2004/04/08 10:48:25 reinelt Exp $
*
* thread handling (mutex, shmem, ...)
*
@@ -26,6 +26,11 @@
*
*
* $Log: thread.c,v $
+ * Revision 1.3 2004/04/08 10:48:25 reinelt
+ * finished plugin_exec
+ * modified thread handling
+ * added '%x' format to qprintf (hexadecimal)
+ *
* Revision 1.2 2004/03/20 07:31:33 reinelt
* support for HD66712 (which has a different RAM layout)
* further threading development
@@ -140,13 +145,14 @@ int shm_create (void **buffer, int size)
}
-void shm_destroy (int shmid)
+void shm_destroy (int shmid, void *buffer)
{
+ shmdt (buffer);
shmctl(shmid, IPC_RMID, NULL);
}
-int thread_create (char *name, void (*thread)(char *name))
+int thread_create (char *name, void (*thread)(void *data), void *data)
{
pid_t pid, ppid;
@@ -158,7 +164,7 @@ int thread_create (char *name, void (*thread)(char *name))
return -1;
case 0:
info ("thread %s starting...", name);
- thread(name);
+ thread(data);
info ("thread %s ended.", name);
exit (0);
default:
diff --git a/thread.h b/thread.h
index a15a9f3..30ea1a9 100644
--- a/thread.h
+++ b/thread.h
@@ -1,4 +1,4 @@
-/* $Id: thread.h,v 1.2 2004/03/20 07:31:33 reinelt Exp $
+/* $Id: thread.h,v 1.3 2004/04/08 10:48:25 reinelt Exp $
*
* thread handling (mutex, shmem, ...)
*
@@ -26,6 +26,11 @@
*
*
* $Log: thread.h,v $
+ * Revision 1.3 2004/04/08 10:48:25 reinelt
+ * finished plugin_exec
+ * modified thread handling
+ * added '%x' format to qprintf (hexadecimal)
+ *
* Revision 1.2 2004/03/20 07:31:33 reinelt
* support for HD66712 (which has a different RAM layout)
* further threading development
@@ -44,8 +49,8 @@ void mutex_unlock (int semid);
void mutex_destroy (int semid);
int shm_create (void **buffer, int size);
-void shm_destroy (int shmid);
+void shm_destroy (int shmid, void *buffer) ;
-int thread_create (char *name, void (*thread)(char *name));
+int thread_create (char *name, void (*thread)(void *data), void *data);
#endif