Catalli's threaded switch
[sliver-openvswitch.git] / utilities / ovs-kill.c
1 /*
2  * Copyright (c) 2008, 2009, 2010 Nicira Networks.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <config.h>
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <getopt.h>
21 #include <signal.h>
22 #include <stdarg.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include "command-line.h"
26 #include "daemon.h"
27 #include "timeval.h"
28 #include "util.h"
29 #include "vlog.h"
30
31 /* -s, --signal: signal to send. */
32 static int sig_nr = SIGTERM;
33
34 /* -f, --force: ignore errors. */
35 static bool force;
36
37 static void cond_error(int err_no, const char *, ...) PRINTF_FORMAT(2, 3);
38
39 static void parse_options(int argc, char *argv[]);
40 static void usage(void);
41
42 int
43 main(int argc, char *argv[])
44 {
45     bool ok = true;
46     int i;
47
48     set_program_name(argv[0]);
49     parse_options(argc, argv);
50
51     argc -= optind;
52     argv += optind;
53     if (argc < 1) {
54         if (!force) {
55             ovs_fatal(0, "need at least one non-option argument; "
56                       "use --help for usage");
57         }
58     }
59
60     for (i = 0; i < argc; i++) {
61         char *pidfile;
62         pid_t pid;
63
64         pidfile = make_pidfile_name(argv[i]);
65         pid = read_pidfile(pidfile);
66         if (pid >= 0) {
67             if (kill(pid, sig_nr) < 0) {
68                 cond_error(errno, "%s: kill(%ld)", pidfile, (long int) pid);
69             }
70         } else {
71             cond_error(-pid, "could not read %s", pidfile);
72         }
73         free(pidfile);
74     }
75
76     return ok || force ? EXIT_SUCCESS : EXIT_FAILURE;
77 }
78
79 static void
80 parse_options(int argc, char *argv[])
81 {
82     static struct option long_options[] = {
83         {"signal",      required_argument, 0, 's'},
84         {"force",       no_argument, 0, 'f'},
85         {"help",        no_argument, 0, 'h'},
86         {"version",     no_argument, 0, 'V'},
87         {0, 0, 0, 0},
88     };
89     char *short_options = long_options_to_short_options(long_options);
90
91     for (;;) {
92         int c;
93
94         c = getopt_long(argc, argv, short_options, long_options, NULL);
95         if (c == -1) {
96             break;
97         }
98
99         switch (c) {
100         case 's':
101             if (atoi(optarg) || !strcmp(optarg, "0")) {
102                 sig_nr = atoi(optarg);
103             } else {
104                 struct signal_name {
105                     const char *name;
106                     int number;
107                 };
108
109                 static const struct signal_name signals[] = {
110 #define SIGNAL(NAME) { #NAME, NAME }
111                     SIGNAL(SIGABRT),
112                     SIGNAL(SIGALRM),
113                     SIGNAL(SIGBUS),
114                     SIGNAL(SIGCHLD),
115                     SIGNAL(SIGCONT),
116                     SIGNAL(SIGFPE),
117                     SIGNAL(SIGHUP),
118                     SIGNAL(SIGILL),
119                     SIGNAL(SIGINT),
120                     SIGNAL(SIGKILL),
121                     SIGNAL(SIGPIPE),
122                     SIGNAL(SIGQUIT),
123                     SIGNAL(SIGSEGV),
124                     SIGNAL(SIGSTOP),
125                     SIGNAL(SIGTERM),
126                     SIGNAL(SIGTSTP),
127                     SIGNAL(SIGTTIN),
128                     SIGNAL(SIGTTOU),
129                     SIGNAL(SIGUSR1),
130                     SIGNAL(SIGUSR2),
131 #ifdef SIGPOLL
132                     SIGNAL(SIGPOLL),
133 #endif
134                     SIGNAL(SIGPROF),
135                     SIGNAL(SIGSYS),
136                     SIGNAL(SIGTRAP),
137                     SIGNAL(SIGURG),
138                     SIGNAL(SIGVTALRM),
139                     SIGNAL(SIGXCPU),
140                     SIGNAL(SIGXFSZ),
141 #undef SIGNAL
142                 };
143                 int i;
144
145                 for (i = 0; i < ARRAY_SIZE(signals); i++) {
146                     const struct signal_name *s = &signals[i];
147                     if (!strcmp(optarg, s->name)
148                         || !strcmp(optarg, s->name + 3)) {
149                         sig_nr = s->number;
150                         goto got_name;
151                     }
152                 }
153                 ovs_fatal(0, "unknown signal \"%s\"", optarg);
154             got_name: ;
155             }
156             break;
157
158         case 'f':
159             force = true;
160             break;
161
162         case 'h':
163             usage();
164
165         case 'V':
166             OVS_PRINT_VERSION(0, 0);
167             exit(EXIT_SUCCESS);
168
169         case '?':
170             exit(EXIT_FAILURE);
171
172         default:
173             abort();
174         }
175     }
176     free(short_options);
177 }
178
179 static void
180 usage(void)
181 {
182     printf("%s: kills a program using a pidfile\n"
183            "usage: %s [OPTIONS] PIDFILE [PIDFILE...]\n"
184            "where PIDFILE is a pidfile created by an Open vSwitch daemon.\n"
185            "\nOptions:\n"
186            "  -s, --signal=NUMBER|NAME  signal to send (default: TERM)\n"
187            "  -f, --force             ignore errors\n"
188            "  -h, --help              display this help message\n"
189            "  -V, --version           display version information\n",
190            program_name, program_name);
191     exit(EXIT_SUCCESS);
192 }
193
194 static void
195 cond_error(int err_no, const char *format, ...)
196 {
197     if (!force) {
198         va_list args;
199
200         fprintf(stderr, "%s: ", program_name);
201         va_start(args, format);
202         vfprintf(stderr, format, args);
203         va_end(args);
204         if (err_no != 0)
205             fprintf(stderr, " (%s)", strerror(err_no));
206         putc('\n', stderr);
207     }
208 }