]> Git Repo - qemu.git/blame - cmd.c
qemu-io: Move functions for registering and running commands
[qemu.git] / cmd.c
CommitLineData
e3aff4f6
AL
1/*
2 * Copyright (c) 2003-2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
8167ee88 15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
e3aff4f6
AL
16 */
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include <ctype.h>
22#include <errno.h>
c32d766a 23#include <sys/time.h>
22a2bdcb 24#include <getopt.h>
e3aff4f6
AL
25
26#include "cmd.h"
737e150e 27#include "block/aio.h"
1de7afc9 28#include "qemu/main-loop.h"
e3aff4f6
AL
29
30#define _(x) x /* not gettext support yet */
31
e3aff4f6
AL
32/* from libxcmd/command.c */
33
e3aff4f6
AL
34static int ncmdline;
35static char **cmdline;
36
e3aff4f6 37
81beeec4 38void add_user_command(char *optarg)
e3aff4f6 39{
ba7806ad 40 cmdline = g_realloc(cmdline, ++ncmdline * sizeof(char *));
81beeec4 41 cmdline[ncmdline-1] = optarg;
e3aff4f6
AL
42}
43
7d7d975c
MK
44static void prep_fetchline(void *opaque)
45{
46 int *fetchable = opaque;
47
a5a5238e 48 qemu_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL);
7d7d975c
MK
49 *fetchable= 1;
50}
51
52static char *get_prompt(void);
53
81beeec4 54void command_loop(void)
e3aff4f6 55{
dd583296 56 int i, done = 0, fetchable = 0, prompted = 0;
81beeec4 57 char *input;
81beeec4
PB
58
59 for (i = 0; !done && i < ncmdline; i++) {
dd583296 60 done = qemuio_command(cmdline[i]);
81beeec4
PB
61 }
62 if (cmdline) {
ba7806ad 63 g_free(cmdline);
81beeec4
PB
64 return;
65 }
7d7d975c 66
81beeec4 67 while (!done) {
7d7d975c
MK
68 if (!prompted) {
69 printf("%s", get_prompt());
70 fflush(stdout);
a5a5238e 71 qemu_set_fd_handler(STDIN_FILENO, prep_fetchline, NULL, &fetchable);
7d7d975c
MK
72 prompted = 1;
73 }
74
a5a5238e 75 main_loop_wait(false);
7d7d975c
MK
76
77 if (!fetchable) {
78 continue;
79 }
dd583296 80
81beeec4
PB
81 input = fetchline();
82 if (input == NULL) {
83 break;
84 }
dd583296
KW
85 done = qemuio_command(input);
86 free(input);
7d7d975c
MK
87
88 prompted = 0;
89 fetchable = 0;
81beeec4 90 }
a5a5238e 91 qemu_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL);
e3aff4f6
AL
92}
93
94/* from libxcmd/input.c */
95
96#if defined(ENABLE_READLINE)
97# include <readline/history.h>
98# include <readline/readline.h>
99#elif defined(ENABLE_EDITLINE)
100# include <histedit.h>
101#endif
102
e3aff4f6
AL
103static char *
104get_prompt(void)
105{
106 static char prompt[FILENAME_MAX + 2 /*"> "*/ + 1 /*"\0"*/ ];
107
108 if (!prompt[0])
109 snprintf(prompt, sizeof(prompt), "%s> ", progname);
110 return prompt;
111}
112
113#if defined(ENABLE_READLINE)
114char *
115fetchline(void)
116{
117 char *line;
118
119 line = readline(get_prompt());
120 if (line && *line)
121 add_history(line);
122 return line;
123}
124#elif defined(ENABLE_EDITLINE)
125static char *el_get_prompt(EditLine *e) { return get_prompt(); }
126char *
127fetchline(void)
128{
129 static EditLine *el;
130 static History *hist;
131 HistEvent hevent;
132 char *line;
133 int count;
134
135 if (!el) {
136 hist = history_init();
137 history(hist, &hevent, H_SETSIZE, 100);
138 el = el_init(progname, stdin, stdout, stderr);
139 el_source(el, NULL);
140 el_set(el, EL_SIGNAL, 1);
141 el_set(el, EL_PROMPT, el_get_prompt);
142 el_set(el, EL_HIST, history, (const char *)hist);
143 }
144 line = strdup(el_gets(el, &count));
145 if (line) {
146 if (count > 0)
147 line[count-1] = '\0';
148 if (*line)
149 history(hist, &hevent, H_ENTER, line);
150 }
151 return line;
152}
153#else
154# define MAXREADLINESZ 1024
155char *
156fetchline(void)
157{
158 char *p, *line = malloc(MAXREADLINESZ);
159
160 if (!line)
161 return NULL;
e3aff4f6
AL
162 if (!fgets(line, MAXREADLINESZ, stdin)) {
163 free(line);
164 return NULL;
165 }
166 p = line + strlen(line);
167 if (p != line && p[-1] == '\n')
168 p[-1] = '\0';
169 return line;
170}
171#endif
172
e3aff4f6
AL
173#define EXABYTES(x) ((long long)(x) << 60)
174#define PETABYTES(x) ((long long)(x) << 50)
175#define TERABYTES(x) ((long long)(x) << 40)
176#define GIGABYTES(x) ((long long)(x) << 30)
177#define MEGABYTES(x) ((long long)(x) << 20)
178#define KILOBYTES(x) ((long long)(x) << 10)
179
e3aff4f6
AL
180#define TO_EXABYTES(x) ((x) / EXABYTES(1))
181#define TO_PETABYTES(x) ((x) / PETABYTES(1))
182#define TO_TERABYTES(x) ((x) / TERABYTES(1))
183#define TO_GIGABYTES(x) ((x) / GIGABYTES(1))
184#define TO_MEGABYTES(x) ((x) / MEGABYTES(1))
185#define TO_KILOBYTES(x) ((x) / KILOBYTES(1))
186
187void
188cvtstr(
189 double value,
190 char *str,
191 size_t size)
192{
8655d2de
PB
193 char *trim;
194 const char *suffix;
e3aff4f6
AL
195
196 if (value >= EXABYTES(1)) {
8655d2de
PB
197 suffix = " EiB";
198 snprintf(str, size - 4, "%.3f", TO_EXABYTES(value));
e3aff4f6 199 } else if (value >= PETABYTES(1)) {
8655d2de
PB
200 suffix = " PiB";
201 snprintf(str, size - 4, "%.3f", TO_PETABYTES(value));
e3aff4f6 202 } else if (value >= TERABYTES(1)) {
8655d2de
PB
203 suffix = " TiB";
204 snprintf(str, size - 4, "%.3f", TO_TERABYTES(value));
e3aff4f6 205 } else if (value >= GIGABYTES(1)) {
8655d2de
PB
206 suffix = " GiB";
207 snprintf(str, size - 4, "%.3f", TO_GIGABYTES(value));
e3aff4f6 208 } else if (value >= MEGABYTES(1)) {
8655d2de
PB
209 suffix = " MiB";
210 snprintf(str, size - 4, "%.3f", TO_MEGABYTES(value));
e3aff4f6 211 } else if (value >= KILOBYTES(1)) {
8655d2de
PB
212 suffix = " KiB";
213 snprintf(str, size - 4, "%.3f", TO_KILOBYTES(value));
214 } else {
215 suffix = " bytes";
216 snprintf(str, size - 6, "%f", value);
217 }
218
219 trim = strstr(str, ".000");
220 if (trim) {
221 strcpy(trim, suffix);
e3aff4f6 222 } else {
8655d2de 223 strcat(str, suffix);
e3aff4f6
AL
224 }
225}
226
227struct timeval
228tsub(struct timeval t1, struct timeval t2)
229{
230 t1.tv_usec -= t2.tv_usec;
231 if (t1.tv_usec < 0) {
232 t1.tv_usec += 1000000;
233 t1.tv_sec--;
234 }
235 t1.tv_sec -= t2.tv_sec;
236 return t1;
237}
238
239double
240tdiv(double value, struct timeval tv)
241{
242 return value / ((double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0));
243}
244
245#define HOURS(sec) ((sec) / (60 * 60))
246#define MINUTES(sec) (((sec) % (60 * 60)) / 60)
247#define SECONDS(sec) ((sec) % 60)
248
249void
250timestr(
251 struct timeval *tv,
252 char *ts,
253 size_t size,
254 int format)
255{
256 double usec = (double)tv->tv_usec / 1000000.0;
257
258 if (format & TERSE_FIXED_TIME) {
259 if (!HOURS(tv->tv_sec)) {
260 snprintf(ts, size, "%u:%02u.%02u",
261 (unsigned int) MINUTES(tv->tv_sec),
262 (unsigned int) SECONDS(tv->tv_sec),
bcd2491a 263 (unsigned int) (usec * 100));
e3aff4f6
AL
264 return;
265 }
266 format |= VERBOSE_FIXED_TIME; /* fallback if hours needed */
267 }
268
269 if ((format & VERBOSE_FIXED_TIME) || tv->tv_sec) {
270 snprintf(ts, size, "%u:%02u:%02u.%02u",
271 (unsigned int) HOURS(tv->tv_sec),
272 (unsigned int) MINUTES(tv->tv_sec),
273 (unsigned int) SECONDS(tv->tv_sec),
bcd2491a 274 (unsigned int) (usec * 100));
e3aff4f6 275 } else {
bcd2491a 276 snprintf(ts, size, "0.%04u sec", (unsigned int) (usec * 10000));
e3aff4f6
AL
277 }
278}
This page took 0.362964 seconds and 4 git commands to generate.