]> arthur.barton.de Git - netatalk.git/blob - contrib/printing/timeout.c
e1776e224ae1cc04d50ec94fe6b286b8b2255160
[netatalk.git] / contrib / printing / timeout.c
1 /*
2  * $Id: timeout.c,v 1.5 2005-04-28 20:49:36 bfernhomberg Exp $
3  */
4
5 #ifdef HAVE_CONFIG_H
6 #include "config.h"
7 #endif /* HAVE_CONFIG_H */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <signal.h>
13 #include <ctype.h>
14 #ifdef HAVE_UNISTD_H
15 #include <unistd.h>
16 #endif /* HAVE_UNISTD_H */
17
18 char **av;
19
20 struct slist {
21         char *name;
22         int num;
23 } sigs[] = {
24 #ifdef SIGHUP
25         { "HUP",        SIGHUP },
26 #endif
27 #ifdef SIGINT
28         { "INT",        SIGINT },
29 #endif
30 #ifdef SIGQUIT
31         { "QUIT",       SIGQUIT },
32 #endif
33 #ifdef SIGILL
34         { "ILL",        SIGILL },
35 #endif
36 #ifdef SIGTRAP
37         { "TRAP",       SIGTRAP },
38 #endif
39 #ifdef SIGABRT
40         { "ABRT",       SIGABRT },
41 #endif
42 #ifdef SIGIOT
43         { "IOT",        SIGIOT },
44 #endif
45 #ifdef SIGEMT
46         { "EMT",        SIGEMT },
47 #endif
48 #ifdef SIGFPE
49         { "FPE",        SIGFPE },
50 #endif
51 #ifdef SIGKILL
52         { "KILL",       SIGKILL },
53 #endif
54 #ifdef SIGBUS
55         { "BUS",        SIGBUS },
56 #endif
57 #ifdef SIGSEGV
58         { "SEGV",       SIGSEGV },
59 #endif
60 #ifdef SIGSYS
61         { "SYS",        SIGSYS },
62 #endif
63 #ifdef SIGPIPE
64         { "PIPE",       SIGPIPE },
65 #endif
66 #ifdef SIGALRM
67         { "ALRM",       SIGALRM },
68 #endif
69 #ifdef SIGTERM
70         { "TERM",       SIGTERM },
71 #endif
72 #ifdef SIGURG
73         { "URG",        SIGURG },
74 #endif
75 #ifdef SIGSTOP
76         { "STOP",       SIGSTOP },
77 #endif
78 #ifdef SIGTSTP
79         { "TSTP",       SIGTSTP },
80 #endif
81 #ifdef SIGCONT
82         { "CONT",       SIGCONT },
83 #endif
84 #ifdef SIGCHLD
85         { "CHLD",       SIGCHLD },
86 #endif
87 #ifdef SIGCLD
88         { "CLD",        SIGCLD },
89 #endif
90 #ifdef SIGTTIN
91         { "TTIN",       SIGTTIN },
92 #endif
93 #ifdef SIGTTOU
94         { "TTOU",       SIGTTOU },
95 #endif
96 #ifdef SIGIO
97         { "IO",         SIGIO },
98 #endif
99 #ifdef SIGXCPU
100         { "XCPU",       SIGXCPU },
101 #endif
102 #ifdef SIGXFSZ
103         { "XFSZ",       SIGXFSZ },
104 #endif
105 #ifdef SIGVTALRM
106         { "VTALRM",     SIGVTALRM },
107 #endif
108 #ifdef SIGPROF
109         { "PROF",       SIGPROF },
110 #endif
111 #ifdef SIGWINCH
112         { "WINCH",      SIGWINCH },
113 #endif
114 #ifdef SIGINFO
115         { "INFO",       SIGINFO },
116 #endif
117 #ifdef SIGUSR1
118         { "USR1",       SIGUSR1 },
119 #endif
120 #ifdef SIGUSR2
121         { "USR2",       SIGUSR2 },
122 #endif
123 #ifdef SIGPWR
124         { "PWR",        SIGPWR },
125 #endif
126         { 0,            0 }
127 };
128
129 void
130 usage()
131 {
132         int i;
133
134         fprintf (stderr, "Usage: %s [-s signal] seconds program [args]\n\n",
135                  *av);
136         fprintf (stderr, "You can use a numerical signal, or one of these:\n");
137
138 #define COLS 8
139
140         for (i = 0; sigs[i].name; i++) {
141                 if (i % COLS == 0)
142                         fprintf (stderr, "\n\t");
143
144                 fprintf (stderr, "%s", sigs[i].name);
145
146                 if ((i + 1) % COLS != 0)
147                         fprintf (stderr, "\t");
148         }
149
150         fprintf (stderr, "\n\n");
151 }
152
153 int
154 main (argc, argv)
155         int argc;
156         char **argv;
157 {
158         int i;
159         int whatsig = SIGTERM;
160         extern char *optarg;
161         extern int optind;
162         int pid;
163
164         av = argv;
165
166         while ((i = getopt (argc, argv, "+s:")) != -1) {
167
168                 switch (i) {
169                 case 's':
170                         if (isdigit (*optarg)) {
171                                 whatsig = atoi (optarg);
172                         } else {
173                                 for (i = 0; sigs[i].name; i++) {
174                                         if (!strcmp (sigs[i].name, optarg)) {
175                                                 whatsig = sigs[i].num;
176                                                 break;
177                                         }
178                                 }
179
180                                 if (!sigs[i].name) {
181                                         fprintf (stderr, 
182                                                  "%s: Unknown signal %s\n",
183                                                  *av, optarg);
184                                         usage();
185                                         exit (1);
186                                 }
187                         }
188
189                         break;
190
191                 default:
192                         usage();
193                         exit (1);
194                 }
195         }
196
197         if (optind > argc - 2) {
198                 usage();
199                 exit (1);
200         }
201
202         if (!isdigit (*argv[optind])) {
203                 fprintf (stderr, "%s: \"seconds\" must be numeric, not %s\n",
204                          *av, argv[optind]);
205                 usage();
206                 exit (1);
207         }
208
209         pid = fork();
210
211         if (pid < 0) {
212                 fprintf (stderr, "%s: fork failed: ", *av);
213                 perror ("fork");
214                 exit (1);
215         } else if (pid == 0) {
216                 int seconds = atoi (argv[optind]);
217
218                 pid = getppid();
219
220                 fclose (stdin);
221                 fclose (stdout);
222                 fclose (stderr);
223
224                 while (seconds-- > 0) {
225                         /*
226                          * too bad there's no SIGPARENT so we have to keep
227                          * polling to find out if it's still there
228                          */
229
230                         if (kill (pid, 0) != 0)
231                                 exit (0);
232
233                         sleep (1);
234                 }
235
236                 kill (pid, whatsig);
237                 exit (0);
238         } else {
239                 execvp (argv[optind + 1], argv + optind + 1);
240
241                 fprintf (stderr, "%s: can't execute ", *av);
242                 perror (argv[optind + 1]);
243                 exit (1);
244         }
245 }