3 * @brief Sensor run by an external process and sent to this one through a pipe
4 * PURELY INCLUDED FOR TESTING PURPOSES
5 * This will work with any sensor that can unbuffer stdout
6 * ... So, although it's not recommended, you could write a sensor purely in something like python
7 * The FastCGI process will handle all the time stamps and stuff
11 #include "../common.h"
15 #include <sys/types.h>
16 #include <sys/socket.h>
17 #include <sys/signal.h>
29 static Piped g_piped[PIPED_MAX];
30 static int g_num_piped = 0;
32 bool Piped_Init(const char * name, int id)
34 if (++g_num_piped > PIPED_MAX)
36 Fatal("Too many sensors; Increase PIPED_MAX from %d in piped.h and recompile", PIPED_MAX);
39 if (socketpair(AF_UNIX, SOCK_STREAM, 0, g_piped[id].sv) != 0)
40 Fatal("socketpair failed - %s", strerror(errno));
42 g_piped[id].pid = fork();
43 if (g_piped[id].pid == 0)
45 dup2(g_piped[id].sv[0], fileno(stdin));
46 dup2(g_piped[id].sv[0], fileno(stdout));
48 if (access(name, X_OK) == 0) //Check we STILL have permissions to start the file
50 execl(name, name, (char*)(NULL)); ///Replace process with desired executable
51 //execv(executablePath,arguments); ///Replace process with desired executable
55 Fatal("Can't execute file %s", name);
57 Fatal("execl error - %s", strerror(errno));
61 g_piped[id].stream = fdopen(g_piped[id].sv[1], "r");
62 setbuf(g_piped[id].stream, NULL);
68 bool Piped_Read(int id, double * value)
70 if (g_piped[id].stream == NULL)
73 static char line[BUFSIZ];
75 fgets(line, BUFSIZ, g_piped[id].stream);
76 int len = strlen(line);
77 //Log(LOGDEBUG, "Read %s (%d) chars", line, len);
78 while (--len >= 0 && len < BUFSIZ && isspace(line[len]))
83 *value = strtod(line, &end);
86 Log(LOGERR, "Couldn't interpret %s as double - %s", line, strerror(errno));
92 bool Piped_Cleanup(int id)
94 fclose(g_piped[id].stream);
95 if (kill(g_piped[id].pid, 15) != 0)
97 Log(LOGWARN, "Couldn't kill piped %d - %s", g_piped[id].pid, strerror(errno));