aboutsummaryrefslogtreecommitdiffstats
path: root/plugin_exec.c
diff options
context:
space:
mode:
authorreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>2004-04-08 10:48:25 +0000
committerreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>2004-04-08 10:48:25 +0000
commit9164b31d32e1bf9724a5d6a3b0a3420497a3c8f5 (patch)
tree9a63ca7ca5300028f833debc12494b2bd70aacbb /plugin_exec.c
parent74bdf66969f00d1398c971a7756426e055c24f1a (diff)
downloadlcd4linux-9164b31d32e1bf9724a5d6a3b0a3420497a3c8f5.tar.gz
[lcd4linux @ 2004-04-08 10:48:23 by reinelt]
finished plugin_exec modified thread handling added '%x' format to qprintf (hexadecimal) git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@410 3ae390bd-cb1e-0410-b409-cd5a39f66f1f
Diffstat (limited to 'plugin_exec.c')
-rw-r--r--plugin_exec.c235
1 files changed, 196 insertions, 39 deletions
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);
}