Fix GCC -static-libstdc++.
[nethome.git] / src / tgkill.c
1 /* $Id$
2    Copyright 2007, Red Hat Inc.  */
3
4 #include <stdio.h>
5 #include <signal.h>
6 #include <stdlib.h>
7 #include <string.h>
8
9 #include <asm/unistd.h>
10 #include <unistd.h>
11 #define tkill(tid, sig) syscall (__NR_tkill, (tid), (sig))
12
13 #define LENGTH(x) (sizeof (x) / sizeof (*(x)))
14
15 struct signal
16   {
17     int signo;
18     const char *name;
19   };
20 static const struct signal sigtab[] =
21   {
22 #ifdef SIG0
23     { SIG0, "0" },
24 #endif
25 #ifdef SIGHUP
26     { SIGHUP, "HUP" },
27 #endif
28 #ifdef SIGINT
29     { SIGINT, "INT" },
30 #endif
31 #ifdef SIGQUIT
32     { SIGQUIT, "QUIT" },
33 #endif
34 #ifdef SIGILL
35     { SIGILL, "ILL" },
36 #endif
37 #ifdef SIGTRAP
38     { SIGTRAP, "TRAP" },
39 #endif
40 #ifdef SIGABRT
41     { SIGABRT, "ABRT" },
42 #endif
43 #ifdef SIGBUS
44     { SIGBUS, "BUS" },
45 #endif
46 #ifdef SIGFPE
47     { SIGFPE, "FPE" },
48 #endif
49 #ifdef SIGKILL
50     { SIGKILL, "KILL" },
51 #endif
52 #ifdef SIGUSR1
53     { SIGUSR1, "USR1" },
54 #endif
55 #ifdef SIGSEGV
56     { SIGSEGV, "SEGV" },
57 #endif
58 #ifdef SIGUSR2
59     { SIGUSR2, "USR2" },
60 #endif
61 #ifdef SIGPIPE
62     { SIGPIPE, "PIPE" },
63 #endif
64 #ifdef SIGALRM
65     { SIGALRM, "ALRM" },
66 #endif
67 #ifdef SIGTERM
68     { SIGTERM, "TERM" },
69 #endif
70 #ifdef SIGSTKFLT
71     { SIGSTKFLT, "STKFLT" },
72 #endif
73 #ifdef SIGCHLD
74     { SIGCHLD, "CHLD" },
75 #endif
76 #ifdef SIGCONT
77     { SIGCONT, "CONT" },
78 #endif
79 #ifdef SIGSTOP
80     { SIGSTOP, "STOP" },
81 #endif
82 #ifdef SIGTSTP
83     { SIGTSTP, "TSTP" },
84 #endif
85 #ifdef SIGTTIN
86     { SIGTTIN, "TTIN" },
87 #endif
88 #ifdef SIGTTOU
89     { SIGTTOU, "TTOU" },
90 #endif
91 #ifdef SIGURG
92     { SIGURG, "URG" },
93 #endif
94 #ifdef SIGXCPU
95     { SIGXCPU, "XCPU" },
96 #endif
97 #ifdef SIGXFSZ
98     { SIGXFSZ, "XFSZ" },
99 #endif
100 #ifdef SIGVTALRM
101     { SIGVTALRM, "VTALRM" },
102 #endif
103 #ifdef SIGPROF
104     { SIGPROF, "PROF" },
105 #endif
106 #ifdef SIGWINCH
107     { SIGWINCH, "WINCH" },
108 #endif
109 #ifdef SIGIO
110     { SIGIO, "IO" },
111 #endif
112 #ifdef SIGPWR
113     { SIGPWR, "PWR" },
114 #endif
115 #ifdef SIGSYS
116     { SIGSYS, "SYS" },
117 #endif
118 #ifdef disableSIGRTMIN  /* initializer element is not constant */
119     { SIGRTMIN, "RTMIN" },
120 #endif
121 #ifdef disableSIGRTMAX  /* initializer element is not constant */
122     { SIGRTMAX, "RTMAX" },
123 #endif
124   };
125
126 static void list (void)
127 {
128   const struct signal *sig;
129
130   for (sig = sigtab; sig < sigtab + LENGTH (sigtab); sig++)
131     printf ("%2d\t%s\n", sig->signo, sig->name);
132   exit (EXIT_SUCCESS);
133 }
134
135 static
136 #ifdef __GNUC__
137   __attribute__((__unused__))
138 #endif
139   void fail (const char *where)
140 {
141   fprintf (stderr, "Error parsing arguments: %s\n", where);
142   exit (EXIT_FAILURE);
143 }
144
145 static int parse_number (const char *text)
146 {
147   char *end;
148   long val;
149
150   val = strtol (text, &end, 0);
151   if (val >= 0 && (int) val == val && (end == NULL || *end == 0))
152     return val;
153
154   return -1;
155 }
156
157 static int parse_signal (const char *text_orig)
158 {
159   const char *text = text_orig;
160   const struct signal *sig;
161   int retval;
162
163   retval = parse_number (text);
164   if (retval >= 0)
165     return retval;
166
167   if (strncasecmp (text, "SIG", 3) == 0)
168     text += 3;
169   for (sig = sigtab; sig < sigtab + LENGTH (sigtab); sig++)
170     if (strcasecmp (sig->name, text) == 0)
171       return sig->signo;
172
173   fail (text_orig);
174   /* NOTREACHED */
175   return -1;
176 }
177
178 static void help (void)
179 {
180   fputs ("\
181 tgkill -h\n\
182 tgkill -l\n\
183 tgkill {-s sigspec | -n sigspec | -sigspec} pid ...\n\
184 ", stdout);
185   exit (EXIT_SUCCESS);
186 }
187
188 int main (int argc, char **argv)
189 {
190   char **argp;
191   int signo;
192
193   if (argc == 2 && strcmp (argv[1], "-h") == 0)
194     help ();
195   if (argc == 2 && strcmp (argv[1], "-l") == 0)
196     list ();
197
198   if (argc > 3 && (strcmp (argv[1], "-s") == 0 || strcmp (argv[1], "-n") == 0))
199     {
200       signo = parse_signal (argv[2]);
201       argp = argv + 3;
202     }
203   else if (argc > 2 && argv[1][0] == '-')
204     {
205       signo = parse_signal (argv [1] + 1);
206       argp = argv + 2;
207     }
208   else
209     fail ("<general>");
210
211   while (argp < argv + argc)
212     {
213       const char *arg = *argp++;
214       int pid;
215
216       pid = parse_number (arg);
217       if (pid == -1)
218         fail (arg);
219
220       if (tkill (pid, signo) != 0)
221         perror (arg);
222     }
223
224   return EXIT_SUCCESS;
225 }