dpoke.c
changeset 1 3e9290bf7249
parent 0 a22a319f5129
child 19 bf780d158f3e
equal deleted inserted replaced
0:a22a319f5129 1:3e9290bf7249
    19     DPOKE_FILE,
    19     DPOKE_FILE,
    20     DPOKE_FUNCTION,
    20     DPOKE_FUNCTION,
    21 };
    21 };
    22 typedef enum DPokeSourceType_en DPokeSourceType;
    22 typedef enum DPokeSourceType_en DPokeSourceType;
    23 
    23 
    24 #define DPOKE_BUFFER 32
    24 #define DPOKE_BUFFER 128
    25 struct DPokeSource_st {
    25 struct DPokeSource_st {
    26     DPokeSourceType type;
    26     DPokeSourceType type;
    27     char *path;
    27     char *path;
    28     int arg;
    28     int arg;
    29 
    29 
    46 
    46 
    47 typedef struct DPokeSource_st DPokeSource;
    47 typedef struct DPokeSource_st DPokeSource;
    48 
    48 
    49 #define LENGTH(X)               (sizeof X / sizeof X[0])
    49 #define LENGTH(X)               (sizeof X / sizeof X[0])
    50 
    50 
    51 char* smprintf(char *fmt, ...) {
    51 char *
    52     va_list fmtargs;
    52 smprintf(char *fmt, ...)
    53     char *ret;
    53 {
    54     int len;
    54         va_list fmtargs;
    55 
    55         char *ret;
    56     va_start(fmtargs, fmt);
    56         int len;
    57     len = vsnprintf(NULL, 0, fmt, fmtargs);
    57 
    58     va_end(fmtargs);
    58         va_start(fmtargs, fmt);
    59 
    59         len = vsnprintf(NULL, 0, fmt, fmtargs);
    60     ret = malloc(++len);
    60         va_end(fmtargs);
    61     if (ret == NULL) {
    61 
    62         perror("malloc");
    62         ret = malloc(++len);
    63         exit(1);
    63         if (ret == NULL) {
    64     }
    64                 perror("malloc");
    65 
    65                 exit(1);
    66     va_start(fmtargs, fmt);
    66         }
    67     vsnprintf(ret, len, fmt, fmtargs);
    67 
    68     va_end(fmtargs);
    68         va_start(fmtargs, fmt);
    69 
    69         vsnprintf(ret, len, fmt, fmtargs);
    70     return ret;
    70         va_end(fmtargs);
    71 }
    71 
    72 
    72         return ret;
    73 
    73 }
    74 void display();
    74 
       
    75 void display(char *v[], size_t vc);
       
    76 void setup(void);
       
    77 void cleanup(int exitcode);
    75 
    78 
    76 extern char* v[];
    79 extern char* v[];
    77 #include "config.h"
    80 #include "config.h"
    78 #ifdef DEBUG
    81 #ifdef DEBUG
    79 #define errprintf(...) fprintf(stderr,...)
    82 #define errprintf(...) fprintf(stderr,__VA_ARGS__)
    80 #else
    83 #else
    81 #define errprintf(...)
    84 #define errprintf(...)
    82 #endif
    85 #endif
    83 
    86 
    84 char* v[LENGTH(sources)];
    87 char* v[LENGTH(sources)];
    85 
    88 
    86 static struct pollfd source_fds[LENGTH(sources)];
    89 static struct pollfd source_fds[LENGTH(sources)];
       
    90 
       
    91 void die(int exitcode) {
       
    92     fprintf(stderr, "Dying with exit code %d\n", exitcode);
       
    93     cleanup(exitcode);
       
    94     exit(exitcode);
       
    95 }
    87 
    96 
    88 void source_open(int source_id) {
    97 void source_open(int source_id) {
    89     DPokeSource *src = &sources[source_id];
    98     DPokeSource *src = &sources[source_id];
    90     //FILE* stream;
    99     //FILE* stream;
    91     int p_stdout[2];
   100     int p_stdout[2];
    92     switch (src->type) {
   101     switch (src->type) {
    93         case DPOKE_PROGRAM:
   102         case DPOKE_PROGRAM:
    94             //stream = popen(src->path, "r");
   103             //stream = popen(src->path, "r");
    95             if (pipe(p_stdout)!=0) {
   104             if (pipe(p_stdout)!=0) {
    96                 perror("pipe");
   105                 perror("pipe");
    97                 exit(7);
   106                 die(7);
    98             }
   107             }
    99             pid_t pid = fork();
   108             pid_t pid = fork();
   100             if (pid < 0) {
   109             if (pid < 0) {
   101                 perror("fork");
   110                 perror("fork");
   102                 exit(7);
   111                 die(7);
   103             } else if (pid == 0) {
   112             } else if (pid == 0) {
   104                 dup2(open("/dev/null",O_RDONLY),0);
   113                 dup2(open("/dev/null",O_RDONLY),0);
   105                 close(p_stdout[0]);
   114                 close(p_stdout[0]);
   106                 dup2(p_stdout[1],1);
   115                 dup2(p_stdout[1],1);
   107                 execl("/bin/sh", "sh", "-c", src->path, NULL);
   116                 execl("/bin/sh", "sh", "-c", src->path, NULL);
   111             src->fd = p_stdout[0];
   120             src->fd = p_stdout[0];
   112             src->pid = pid;
   121             src->pid = pid;
   113             break;
   122             break;
   114         default:
   123         default:
   115             errprintf("Don't know how to handle source type %d.\n",src->type);
   124             errprintf("Don't know how to handle source type %d.\n",src->type);
   116             exit(2);
   125             die(2);
   117     }
   126     }
   118     //src->stream = stream;
   127     //src->stream = stream;
   119     //src->fd = fileno(stream);
   128     //src->fd = fileno(stream);
   120     src->buffer_usage = 0;
   129     src->buffer_usage = 0;
   121     src->status = DPOKE_STARTED;
   130     src->status = DPOKE_STARTED;
   136                         sources[i].status = DPOKE_FAIL; break;
   145                         sources[i].status = DPOKE_FAIL; break;
   137                     case DPOKE_RUNNING:
   146                     case DPOKE_RUNNING:
   138                         sources[i].status = DPOKE_DIED; break;
   147                         sources[i].status = DPOKE_DIED; break;
   139                     default:
   148                     default:
   140                         errprintf("#%d died in state %d. Whaddafuck?!\n",i,sources[i].status);
   149                         errprintf("#%d died in state %d. Whaddafuck?!\n",i,sources[i].status);
   141                         exit(8);
   150                         die(8);
   142                 }
   151                 }
   143             }
   152             }
   144     }
   153     }
   145 }
   154 }
   146 
   155 
   153 
   162 
   154 double dpoke_time() {
   163 double dpoke_time() {
   155     struct timespec tp;
   164     struct timespec tp;
   156     if (clock_gettime(CLOCK_MONOTONIC,&tp)) {
   165     if (clock_gettime(CLOCK_MONOTONIC,&tp)) {
   157         perror("clock_gettime");
   166         perror("clock_gettime");
   158         exit(5);
   167         die(5);
   159     }
   168     }
   160     return tp.tv_sec + tp.tv_nsec*1E-9;
   169     return tp.tv_sec + tp.tv_nsec*1E-9;
   161 }
   170 }
   162 
   171 
   163 int main(int argc, char* argv[]) {
   172 int main(int argc, char* argv[]) {
       
   173     setup();
   164     struct sigaction act;
   174     struct sigaction act;
   165 
   175 
   166     memset (&act, 0, sizeof(act));
   176     memset (&act, 0, sizeof(act));
   167     act.sa_handler = sigchld_hdl;
   177     act.sa_handler = sigchld_hdl;
   168     if (sigaction(SIGCHLD, &act, 0)) {
   178     if (sigaction(SIGCHLD, &act, 0)) {
   169         perror ("sigaction");
   179         perror ("sigaction");
   170         exit(6);
   180         die(6);
   171     }
   181     }
   172 
   182 
   173     for (int i = 0; i < LENGTH(sources); i++ ) {
   183     for (int i = 0; i < LENGTH(sources); i++ ) {
   174         source_open(i);
   184         source_open(i);
   175         v[i] = sources[i].current;
   185         v[i] = sources[i].current;
   184                 continue;
   194                 continue;
   185         }
   195         }
   186         for (int i = 0; i < LENGTH(sources); i++) {
   196         for (int i = 0; i < LENGTH(sources); i++) {
   187             DPokeSource *src = sources+i;
   197             DPokeSource *src = sources+i;
   188             if (source_fds[i].revents & POLLIN) {
   198             if (source_fds[i].revents & POLLIN) {
       
   199                 errprintf("Event: %d\n", source_fds[i].revents);
   189                 int data_read = read(src->fd,src->buffer+src->buffer_usage,DPOKE_BUFFER-src->buffer_usage);
   200                 int data_read = read(src->fd,src->buffer+src->buffer_usage,DPOKE_BUFFER-src->buffer_usage);
   190                 if (data_read>0) {
   201                 if (data_read>0) {
   191                     src->buffer_usage += data_read;
   202                     src->buffer_usage += data_read;
   192                     if (src->buffer_usage==DPOKE_BUFFER) {
   203                     if (src->buffer_usage>=DPOKE_BUFFER) {
   193                         errprintf("Buffer is full for #%d.\n",i);
   204                         fprintf(stderr, "Buffer is full for #%d. Resetting.\n",i);
       
   205                         src->buffer_usage = 0;
   194                     }
   206                     }
   195                     src->buffer[src->buffer_usage] = '\0';
   207                     src->buffer[src->buffer_usage] = '\0';
   196                     char* eolpos = strchr(src->buffer + src->buffer_usage - data_read,'\n');
   208                     char* eolpos = strchr(src->buffer + src->buffer_usage - data_read,'\n');
   197                     if (eolpos) {
   209                     if (eolpos) {
   198                         memcpy(src->current,src->buffer,eolpos-src->buffer);
   210                         memcpy(src->current,src->buffer,eolpos-src->buffer);
   201                         memmove(src->buffer,eolpos + 1,src->buffer_usage + 1);
   213                         memmove(src->buffer,eolpos + 1,src->buffer_usage + 1);
   202                     }
   214                     }
   203                     if (src->status == DPOKE_STARTED)
   215                     if (src->status == DPOKE_STARTED)
   204                         src->status = DPOKE_RUNNING;
   216                         src->status = DPOKE_RUNNING;
   205                 } else {
   217                 } else {
       
   218                     fprintf(stderr, "Buffer usage: %d\n", src->buffer_usage);
   206                     perror("read");
   219                     perror("read");
   207                     exit(3);
   220                     die(3);
   208                 }
   221                 }
   209             } else if ((source_fds[i].revents & POLLHUP)||(src->status==DPOKE_DIED)) {
   222             } else if ((source_fds[i].revents & POLLHUP)||(src->status==DPOKE_DIED)) {
   210                 errprintf("#%d HUP\n",i);
   223                 errprintf("#%d HUP\n",i);
   211                 source_close(i);
   224                 source_close(i);
   212                 if (src->status==DPOKE_STARTED)
   225                 if (src->status==DPOKE_STARTED)
   222                 strcpy(src->current,FAILURE_MSG);
   235                 strcpy(src->current,FAILURE_MSG);
   223             }
   236             }
   224         }
   237         }
   225         double curtime = dpoke_time();
   238         double curtime = dpoke_time();
   226         if ((curtime-prevtime)>MINTIME) {
   239         if ((curtime-prevtime)>MINTIME) {
   227             display();
   240             display(v,LENGTH(sources));
   228             prevtime = curtime;
   241             prevtime = curtime;
   229             sleeptime = 10000;
   242             sleeptime = 10000;
   230         } else {
   243         } else {
   231             double sleepd = (prevtime+MINTIME - curtime)*1000;
   244             double sleepd = (prevtime+MINTIME - curtime)*1000;
   232             sleeptime = ceil(sleepd);
   245             sleeptime = ceil(sleepd);
   233             errprintf("%f %f %f %f\n",prevtime,curtime,MINTIME,sleepd);
   246             errprintf("%f %f %f %f\n",prevtime,curtime,MINTIME,sleepd);
   234         }
   247         }
   235         errprintf("Will sleep for %d\n",sleeptime);
   248         errprintf("Will sleep for %d\n",sleeptime);
   236     }
   249     }
       
   250     cleanup(0);
   237     return 0;
   251     return 0;
   238 }
   252 }
   239 /*
   253 /*
   240 ABCnDEF0
   254 ABCnDEF0
   241 01234567
   255 01234567