6444e8bd75feb658ded19c8fbf70e61423e319e3
[matches/MCTX3420.git] / server / sensors / piped.c
1 /**
2  * @file piped.h
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
8  */
9
10 #include "../log.h"
11 #include "../common.h"
12
13 #include "piped.h"
14
15 #include <sys/types.h>
16 #include <sys/socket.h>
17 #include <sys/signal.h>
18 #include <ctype.h>
19
20
21 typedef struct
22 {
23         int pid;
24         int sv[2];
25         FILE * stream;
26         
27 } Piped;
28
29 static Piped g_piped[PIPED_MAX];
30 static int g_num_piped = 0;
31
32 bool Piped_Init(const char * name, int id)
33 {
34         if (++g_num_piped > PIPED_MAX)
35         {
36                 Fatal("Too many sensors; Increase PIPED_MAX from %d in piped.h and recompile", PIPED_MAX);
37         }
38
39         if (socketpair(AF_UNIX, SOCK_STREAM, 0, g_piped[id].sv) != 0)
40                         Fatal("socketpair failed - %s", strerror(errno));
41
42         g_piped[id].pid = fork();
43         if (g_piped[id].pid == 0)
44         {
45                 dup2(g_piped[id].sv[0], fileno(stdin));
46                 dup2(g_piped[id].sv[0], fileno(stdout));
47
48                 if (access(name, X_OK) == 0) //Check we STILL have permissions to start the file
49                 {
50                         execl(name, name, (char*)(NULL)); ///Replace process with desired executable
51                         //execv(executablePath,arguments); ///Replace process with desired executable
52                 }
53                 else
54                 {
55                         Fatal("Can't execute file %s", name);
56                 }
57                 Fatal("execl error - %s", strerror(errno));
58         }
59         else
60         {
61                 g_piped[id].stream = fdopen(g_piped[id].sv[1], "r");
62                 setbuf(g_piped[id].stream, NULL);
63         }
64         return true;
65         
66 }
67
68 bool Piped_Read(int id, double * value)
69 {
70         if (g_piped[id].stream == NULL)
71                 return false;
72
73         static char line[BUFSIZ];
74         
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]))
79         {
80                 line[len] = '\0';
81         }
82         char * end = line;
83         *value = strtod(line, &end);
84         if (*end != '\0')
85         {
86                 Log(LOGERR, "Couldn't interpret %s as double - %s", line, strerror(errno));
87                 return false;
88         }
89         return true;
90 }
91
92 bool Piped_Cleanup(int id)
93 {
94         fclose(g_piped[id].stream);
95         if (kill(g_piped[id].pid, 15) != 0)
96         {
97                 Log(LOGWARN, "Couldn't kill piped %d - %s", g_piped[id].pid, strerror(errno));
98                 return false;
99         }
100         return true;
101 }

UCC git Repository :: git.ucc.asn.au