astribank_is_starting.c: do have timeout (typo)
[dahdi/tools.git] / xpp / astribank_is_starting.c
1 #include "../autoconfig.h"
2 #include <sys/types.h>
3 #include <sys/ipc.h>
4 #include <sys/sem.h>
5 #include <errno.h>
6 #include <getopt.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <time.h>
11
12 static char             *progname;
13 static const key_t      key_astribanks = 0xAB11A0;
14 static int              debug;
15 static int              verbose;
16 static int              timeout_seconds = 60;
17
18 /* If libc provides no timeout variant: try to do without it: */
19 #ifndef HAVE_SEMTIMEDOP
20 #define  semtimedop(sem, ops, n, timeout)    semop(sem, ops, n)
21 #endif
22
23 static void usage(void)
24 {
25         fprintf(stderr, "Usage: %s [-d] [-t <seconds>] [-a|-r|-w]\n", progname);
26         exit(1);
27 }
28
29 static int absem_get(int createit)
30 {
31         int     flags = (createit) ? IPC_CREAT | 0644 : 0;
32         int     absem;
33
34         if((absem = semget(key_astribanks, 1, flags)) < 0)
35                 absem = -errno;
36         return absem;
37 }
38
39 static int absem_touch(void)
40 {
41         int             absem;
42
43         if((absem = absem_get(1)) < 0) {
44                 perror(__FUNCTION__);
45                 return absem;
46         }
47         if(semctl(absem, 0, SETVAL, 0) < 0) {
48                 perror("SETVAL");
49                 return -errno;
50         }
51         if(debug)
52                 fprintf(stderr, "%s: touched absem\n", progname);
53         if(verbose)
54                 printf("Astribanks initialization is starting\n");
55         return 0;
56 }
57
58 static int absem_remove(void)
59 {
60         int     absem;
61
62         if((absem = absem_get(0)) < 0) {
63                 if(absem == -ENOENT) {
64                         if(debug)
65                                 fprintf(stderr, "%s: absem already removed\n", progname);
66                         return 0;
67                 }
68                 perror(__FUNCTION__);
69                 return absem;
70         }
71         if(semctl(absem, 0, IPC_RMID, 0) < 0) {
72                 perror("RMID");
73                 return -errno;
74         }
75         if(debug)
76                 fprintf(stderr, "%s: removed absem\n", progname);
77         if(verbose)
78                 printf("Astribanks initialization is done\n");
79         return 0;
80 }
81
82 static int absem_wait(void)
83 {
84         int             absem;
85         struct sembuf   sops;
86         long            now;
87         long            start_wait;
88         struct timespec timeout;
89
90         if((absem = absem_get(0)) < 0) {
91                 perror(__FUNCTION__);
92                 return absem;
93         }
94         sops.sem_num = 0;
95         sops.sem_op = -1;
96         sops.sem_flg = 0;
97         start_wait = time(NULL);
98         timeout.tv_sec = timeout_seconds;
99         timeout.tv_nsec = 0;
100         if(semtimedop(absem, &sops, 1, &timeout) < 0) {
101                 switch(errno) {
102                 case EIDRM:     /* Removed -- OK */
103                         break;
104                 case EAGAIN:    /* Timeout -- Report */
105                         fprintf(stderr, "Astribanks waiting timed out\n");
106                         return -errno;
107                 default:        /* Unexpected errors */
108                         perror("semop");
109                         return -errno;
110                 }
111                 /* fall-thgough */
112         }
113         now = time(NULL);
114         if(debug)
115                 fprintf(stderr, "%s: waited on absem %ld seconds\n", progname, now - start_wait);
116         if(verbose)
117                 printf("Finished after %ld seconds\n", now - start_wait);
118         return 0;
119 }
120
121 static int absem_detected(void)
122 {
123         int     absem;
124
125         if((absem = absem_get(0)) < 0) {
126                 if(debug)
127                         fprintf(stderr, "%s: absem does not exist\n", progname);
128                 return absem;
129         }
130         if(debug)
131                 fprintf(stderr, "%s: absem exists\n", progname);
132         if(verbose)
133                 printf("Astribanks are initializing...\n");
134         return 0;
135 }
136
137 int main(int argc, char *argv[])
138 {
139         const char      options[] = "dvarwt:h";
140         int             val;
141
142         progname = argv[0];
143         while (1) {
144                 int     c;
145                 int     t;
146
147                 c = getopt (argc, argv, options);
148                 if (c == -1)
149                         break;
150
151                 switch (c) {
152                         case 'd':
153                                 debug++;
154                                 break;
155                         case 'v':
156                                 verbose++;
157                                 break;
158                         case 't':
159                                 t = atoi(optarg);
160                                 if(t <= 0) {
161                                         fprintf(stderr,
162                                                 "%s: -t expect a positive number of seconds: '%s'\n",
163                                                 progname, optarg);
164                                         usage();
165                                 }
166                                 timeout_seconds = t;
167                                 break;
168                         case 'a':
169                                 if((val = absem_touch()) < 0) {
170                                         fprintf(stderr, "%s: Add failed: %d\n", progname, val);
171                                         return 1;
172                                 }
173                                 return 0;
174                         case 'r':
175                                 if((val = absem_remove()) < 0) {
176                                         fprintf(stderr, "%s: Remove failed: %d\n", progname, val);
177                                         return 1;
178                                 }
179                                 return 0;
180                         case 'w':
181                                 if((val = absem_wait()) < 0) {
182                                         fprintf(stderr, "%s: Wait failed: %d\n", progname, val);
183                                         return 1;
184                                 }
185                                 return 0;
186                         case 'h':
187                         default:
188                                 fprintf(stderr, "Unknown option '%c'\n", c);
189                                 usage();
190                 }
191         }
192         val = absem_detected();
193         return (val == 0) ? 0 : 1;
194 }