rspan.c
1#include <signal.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5#include <sys/time.h>
6#include <time.h>
7#include <unistd.h>
8
9static const char* usage = "usage: rspan INT FILE [ARG ...]\n"
10"\n"
11" INT : interval in seconds\n"
12" FILE : file path to executable\n"
13" ARG : list of arguments for executable\n";
14
15static int command_argc;
16static char **command;
17
18static void die(int, const char*);
19static void handler(int);
20static void init_timer(int, void (*)(int));
21static unsigned long mix(unsigned long, unsigned long, unsigned long);
22
23unsigned long
24mix(unsigned long a, unsigned long b, unsigned long c)
25{
26 a=a-b; a=a-c; a=a^(c >> 13);
27 b=b-c; b=b-a; b=b^(a << 8);
28 a=a-b; a=a-c; a=a^(c >> 12);
29 b=b-c; b=b-a; b=b^(a << 16);
30 a=a-b; a=a-c; a=a^(c >> 3);
31 b=b-c; b=b-a; b=b^(a << 10);
32 c=c-a; c=c-b; c=c^(b >> 15);
33 return c;
34}
35
36void
37die(int code, const char *msg)
38{
39 int i;
40
41 if (msg != NULL)
42 fprintf(stderr, "%s\n", msg);
43
44 if (command != NULL) {
45 for (i = 0; i < command_argc; i++)
46 free(command[i]);
47 free(command);
48 }
49
50 exit(code);
51}
52
53void
54init_timer(int timeout, void (*func)(int))
55{
56 struct itimerval it_val;
57
58 it_val.it_value.tv_sec = timeout;
59 it_val.it_value.tv_usec = 0;
60 it_val.it_interval.tv_sec = 0;
61 it_val.it_interval.tv_usec = 0;
62
63 if (signal(SIGALRM, func) == SIG_ERR)
64 die(1, "signal handler couldn't be created");
65 if (setitimer(ITIMER_REAL, &it_val, NULL) == -1)
66 die(1, "timer couldn't initialize");
67}
68
69void
70handler(int signum)
71{
72 execvp(command[0], command);
73 die(0, NULL);
74}
75
76int
77main (int argc, char *argv[])
78{
79 unsigned long seed = mix(clock(), time(NULL), getpid());
80 int c, i, s;
81
82 if (argc == 1)
83 die(0, usage);
84
85 if (sscanf(argv[1], "%i", &s) != 1 || s <= 0)
86 die(1, "interval must be a positive integer");
87
88 if ((command_argc = argc - 1) < 2)
89 die(1, "please add something to execute");
90
91 command = (char **)malloc((command_argc) * sizeof(char *));
92 for (i = 2; i < argc; i++) {
93 *command = (char *)malloc(strlen(argv[i]) + 1);
94 strncpy(*command, argv[i], strlen(argv[i]) + 1);
95 command++;
96 }
97 *command = NULL;
98 command -= (command_argc - 1);
99
100 srand(seed);
101 s = rand() % s + 1;
102 init_timer(s, &handler);
103
104 while ((c = getchar()));
105
106 /* unreachable */
107 return 0;
108}