annotate lib-src/=timer.c @ 66:5793fbcb9ac1

Initial revision
author Richard M. Stallman <rms@gnu.org>
date Tue, 19 Jun 1990 20:28:34 +0000
parents a55a3ac41924
children 1aa96958b728
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
45
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
1 #include <stdio.h>
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
2 #include <signal.h>
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
3 #include <fcntl.h> /* FASYNC */
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
4 #ifdef USG /* FASYNC for SysV */
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
5 #include <sys/file.h>
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
6 #endif
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
7 #include <sys/time.h> /* itimer */
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
8 #include <sys/types.h> /* time_t */
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
9
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
10 extern int errno;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
11 extern char *sys_errlist[], *malloc();
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
12 extern time_t time();
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
13
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
14 #define MAXEVENTS 256
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
15 #define FS 1 /* field seperator for input */
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
16
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
17 struct event {
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
18 char *token;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
19 time_t reply_at;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
20 } *events[MAXEVENTS];
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
21
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
22 int slot; /* The next open place in the events array */
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
23 int mevent = 0; /* 1+ the highest event number */
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
24 char *pname; /* programme name for error messages */
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
25
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
26 /* Accepts a string of two fields seperated by a ';'
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
27 * First field is string for getdate, saying when to wake-up.
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
28 * Second field is a token to identify the request.
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
29 */
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
30 struct event *
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
31 schedule(str)
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
32 char *str;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
33
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
34 {
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
35 extern time_t getdate();
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
36 extern char *strcpy();
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
37 time_t now;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
38 register char *p;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
39 static struct event e;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
40
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
41 for(p = str; *p && *p != FS; p++);
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
42 if (!*p) {
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
43 (void)fprintf(stderr, "%s: bad input format: %s", pname, str);
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
44 return((struct event *)NULL);
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
45 }
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
46 *p++ = 0;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
47
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
48 if ((e.reply_at = getdate(str, NULL)) - time(&now) < 0) {
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
49 (void)fprintf(stderr, "%s: bad time spec: %s%c%s", pname, str, FS, p);
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
50 return((struct event *)NULL);
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
51 }
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
52
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
53 if ((e.token = malloc((unsigned)strlen(p) + 1)) == NULL) {
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
54 (void)fprintf(stderr, "%s: malloc %s: %s%c%s",
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
55 pname, sys_errlist[errno], str, FS, p);
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
56 return((struct event *)NULL);
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
57 }
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
58 (void)strcpy(e.token,p);
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
59
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
60 return(&e);
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
61 }
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
62
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
63 void
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
64 notify()
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
65
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
66 {
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
67 time_t now, tdiff;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
68 register int i, newmax = 0;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
69 /* I prefer using the interval timer rather than alarm(); the latter
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
70 could be substituted if portability requires it. */
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
71 struct itimerval itimer;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
72
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
73 now = time((time_t *)NULL);
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
74 slot = mevent;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
75 itimer.it_interval.tv_sec = itimer.it_interval.tv_usec = 0;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
76 itimer.it_value.tv_usec = 0;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
77 itimer.it_value.tv_sec = -1;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
78
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
79 for(i=0; i < mevent; i++) {
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
80 while (events[i] && events[i]->reply_at <= now) {
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
81 (void)fputs(events[i]->token, stdout);
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
82 free(events[i]->token);
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
83 free((char *)events[i]);
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
84 events[i] = 0;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
85 }
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
86
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
87 if (events[i]) {
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
88 newmax = i+1;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
89 if ((tdiff = events[i]->reply_at - now) < (time_t)itimer.it_value.tv_sec
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
90 || itimer.it_value.tv_sec < 0)
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
91 /* next timeout */
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
92 itimer.it_value.tv_sec = (long)tdiff;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
93 } else {
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
94 /* Keep slot as the lowest unused events element */
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
95 if (i < slot) slot = i;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
96 }
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
97 }
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
98 /* if the array is full to mevent, slot should be the next available spot */
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
99 if (slot > (mevent = newmax)) slot = mevent;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
100 /* If there's no more events, SIGIO should be next wake-up */
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
101 if (mevent) (void)setitimer(ITIMER_REAL, &itimer, (struct itimerval *)NULL);
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
102 }
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
103
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
104 void
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
105 getevent()
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
106
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
107 {
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
108 extern char *memcpy(), *fgets();
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
109 struct event *ep;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
110 char buf[256];
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
111
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
112 /* in principle the itimer should be disabled on entry to this function,
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
113 but it really doesn't make any important difference if it isn't */
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
114
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
115 if (fgets(buf, sizeof(buf), stdin) == NULL) exit(0);
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
116
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
117 if (slot == MAXEVENTS)
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
118 (void)fprintf(stderr, "%s: too many events: %s", pname, buf);
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
119
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
120 else {
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
121 if ((events[slot] = (struct event *)malloc((sizeof(struct event))))
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
122 == NULL)
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
123 (void)fprintf(stderr,"%s: malloc %s: %s", pname, sys_errlist[errno],buf);
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
124
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
125 else {
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
126 if ((ep = schedule(buf)) == NULL)
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
127 free((char *)events[slot]), events[slot] = 0;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
128
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
129 else {
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
130 (void)memcpy((char *)events[slot],(char *)ep,sizeof(struct event));
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
131 if (slot == mevent) mevent++;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
132 } /* schedule */
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
133 } /* malloc */
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
134 } /* limit events */
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
135 /* timing, timing. Who knows what this interrupted, or if it said "now"? */
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
136 notify();
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
137 }
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
138
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
139 /*ARGSUSED*/
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
140 int
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
141 main(argc, argv)
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
142 int argc;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
143 char **argv;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
144
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
145 {
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
146 for (pname = argv[0] + strlen(argv[0]); *pname != '/' && pname != argv[0];
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
147 pname--);
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
148 if (*pname == '/') pname++;
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
149
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
150 (void)signal(SIGIO, getevent);
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
151 (void)signal(SIGALRM, notify);
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
152 (void)fcntl(0, F_SETFL, FASYNC);
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
153
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
154 while (1) pause();
a55a3ac41924 Initial revision
root <root>
parents:
diff changeset
155 }