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