]> git.proxmox.com Git - mirror_ovs.git/blame - utilities/ovs-kill.c
ovs-ofctl: Fix del-flows command parsing bugs.
[mirror_ovs.git] / utilities / ovs-kill.c
CommitLineData
064af421 1/*
ff8bb7e7 2 * Copyright (c) 2008, 2009, 2010 Nicira Networks.
064af421 3 *
a14bc59f
BP
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:
064af421 7 *
a14bc59f
BP
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.
064af421
BP
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. */
32static int sig_nr = SIGTERM;
33
34/* -f, --force: ignore errors. */
35static bool force;
36
37static void cond_error(int err_no, const char *, ...) PRINTF_FORMAT(2, 3);
38
39static void parse_options(int argc, char *argv[]);
40static void usage(void);
41
42int
43main(int argc, char *argv[])
44{
45 bool ok = true;
46 int i;
47
48 set_program_name(argv[0]);
064af421
BP
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
79static void
80parse_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
179static void
180usage(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
194static void
195cond_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}