]> git.proxmox.com Git - qemu.git/blobdiff - cmd.c
osdep: introduce qemu_anon_ram_free to free qemu_anon_ram_alloc-ed memory
[qemu.git] / cmd.c
diff --git a/cmd.c b/cmd.c
index cc70311b9f2ddbcd0da1e9298692b4ac2226b66e..10a8688b2d25f47e4c552b4ec9ec675dc62b62f7 100644 (file)
--- a/cmd.c
+++ b/cmd.c
@@ -24,6 +24,8 @@
 #include <getopt.h>
 
 #include "cmd.h"
+#include "block/aio.h"
+#include "qemu/main-loop.h"
 
 #define _(x)   x       /* not gettext support yet */
 
@@ -44,13 +46,11 @@ compare(const void *a, const void *b)
                      ((const cmdinfo_t *)b)->name);
 }
 
-void
-add_command(
-       const cmdinfo_t *ci)
+void add_command(const cmdinfo_t *ci)
 {
-       cmdtab = realloc((void *)cmdtab, ++ncmds * sizeof(*cmdtab));
-       cmdtab[ncmds - 1] = *ci;
-       qsort(cmdtab, ncmds, sizeof(*cmdtab), compare);
+    cmdtab = g_realloc((void *)cmdtab, ++ncmds * sizeof(*cmdtab));
+    cmdtab[ncmds - 1] = *ci;
+    qsort(cmdtab, ncmds, sizeof(*cmdtab), compare);
 }
 
 static int
@@ -121,16 +121,10 @@ find_command(
        return NULL;
 }
 
-void
-add_user_command(char *optarg)
+void add_user_command(char *optarg)
 {
-       ncmdline++;
-       cmdline = realloc(cmdline, sizeof(char*) * (ncmdline));
-       if (!cmdline) {
-               perror("realloc");
-               exit(1);
-       }
-       cmdline[ncmdline-1] = optarg;
+    cmdline = g_realloc(cmdline, ++ncmdline * sizeof(char *));
+    cmdline[ncmdline-1] = optarg;
 }
 
 static int
@@ -149,57 +143,85 @@ add_args_command(
        args_func = af;
 }
 
-void
-command_loop(void)
+static void prep_fetchline(void *opaque)
 {
-       int             c, i, j = 0, done = 0;
-       char            *input;
-       char            **v;
-       const cmdinfo_t *ct;
+    int *fetchable = opaque;
 
-       for (i = 0; !done && i < ncmdline; i++) {
-               input = strdup(cmdline[i]);
-               if (!input) {
-                       fprintf(stderr,
-                               _("cannot strdup command '%s': %s\n"),
-                               cmdline[i], strerror(errno));
-                       exit(1);
-               }
-               v = breakline(input, &c);
-               if (c) {
-                       ct = find_command(v[0]);
-                       if (ct) {
-                               if (ct->flags & CMD_FLAG_GLOBAL)
-                                       done = command(ct, c, v);
-                               else {
-                                       j = 0;
-                                       while (!done && (j = args_command(j)))
-                                               done = command(ct, c, v);
-                               }
-                       } else
-                               fprintf(stderr, _("command \"%s\" not found\n"),
-                                       v[0]);
-               }
-               doneline(input, v);
-       }
-       if (cmdline) {
-               free(cmdline);
-               return;
-       }
-       while (!done) {
-               if ((input = fetchline()) == NULL)
-                       break;
-               v = breakline(input, &c);
-               if (c) {
-                       ct = find_command(v[0]);
-                       if (ct)
-                               done = command(ct, c, v);
-                       else
-                               fprintf(stderr, _("command \"%s\" not found\n"),
-                                       v[0]);
-               }
-               doneline(input, v);
+    qemu_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL);
+    *fetchable= 1;
+}
+
+static char *get_prompt(void);
+
+void command_loop(void)
+{
+    int c, i, j = 0, done = 0, fetchable = 0, prompted = 0;
+    char *input;
+    char **v;
+    const cmdinfo_t *ct;
+
+    for (i = 0; !done && i < ncmdline; i++) {
+        input = strdup(cmdline[i]);
+        if (!input) {
+            fprintf(stderr, _("cannot strdup command '%s': %s\n"),
+                    cmdline[i], strerror(errno));
+            exit(1);
+        }
+        v = breakline(input, &c);
+        if (c) {
+            ct = find_command(v[0]);
+            if (ct) {
+                if (ct->flags & CMD_FLAG_GLOBAL) {
+                    done = command(ct, c, v);
+                } else {
+                    j = 0;
+                    while (!done && (j = args_command(j))) {
+                        done = command(ct, c, v);
+                    }
+                }
+            } else {
+                fprintf(stderr, _("command \"%s\" not found\n"), v[0]);
+            }
        }
+        doneline(input, v);
+    }
+    if (cmdline) {
+        g_free(cmdline);
+        return;
+    }
+
+    while (!done) {
+        if (!prompted) {
+            printf("%s", get_prompt());
+            fflush(stdout);
+            qemu_set_fd_handler(STDIN_FILENO, prep_fetchline, NULL, &fetchable);
+            prompted = 1;
+        }
+
+        main_loop_wait(false);
+
+        if (!fetchable) {
+            continue;
+        }
+        input = fetchline();
+        if (input == NULL) {
+            break;
+        }
+        v = breakline(input, &c);
+        if (c) {
+            ct = find_command(v[0]);
+            if (ct) {
+                done = command(ct, c, v);
+            } else {
+                fprintf(stderr, _("command \"%s\" not found\n"), v[0]);
+            }
+        }
+        doneline(input, v);
+
+        prompted = 0;
+        fetchable = 0;
+    }
+    qemu_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL);
 }
 
 /* from libxcmd/input.c */
@@ -270,8 +292,6 @@ fetchline(void)
 
        if (!line)
                return NULL;
-       printf("%s", get_prompt());
-       fflush(stdout);
        if (!fgets(line, MAXREADLINESZ, stdin)) {
                free(line);
                return NULL;
@@ -287,7 +307,8 @@ static char *qemu_strsep(char **input, const char *delim)
 {
     char *result = *input;
     if (result != NULL) {
-        char *p = result;
+        char *p;
+
         for (p = result; *p != '\0'; p++) {
             if (strchr(delim, *p)) {
                 break;
@@ -303,29 +324,32 @@ static char *qemu_strsep(char **input, const char *delim)
     return result;
 }
 
-char **
-breakline(
-       char    *input,
-       int     *count)
+char **breakline(char *input, int *count)
 {
-       int     c = 0;
-       char    *p;
-       char    **rval = calloc(sizeof(char *), 1);
-
-       while (rval && (p = qemu_strsep(&input, " ")) != NULL) {
-               if (!*p)
-                       continue;
-               c++;
-               rval = realloc(rval, sizeof(*rval) * (c + 1));
-               if (!rval) {
-                       c = 0;
-                       break;
-               }
-               rval[c - 1] = p;
-               rval[c] = NULL;
-       }
-       *count = c;
-       return rval;
+    int c = 0;
+    char *p;
+    char **rval = calloc(sizeof(char *), 1);
+    char **tmp;
+
+    while (rval && (p = qemu_strsep(&input, " ")) != NULL) {
+        if (!*p) {
+            continue;
+        }
+        c++;
+        tmp = realloc(rval, sizeof(*rval) * (c + 1));
+        if (!tmp) {
+            free(rval);
+            rval = NULL;
+            c = 0;
+            break;
+        } else {
+            rval = tmp;
+        }
+        rval[c - 1] = p;
+        rval[c] = NULL;
+    }
+    *count = c;
+    return rval;
 }
 
 void
@@ -361,7 +385,7 @@ cvtnum(
        if (sp[1] != '\0')
                return -1LL;
 
-       c = tolower(*sp);
+       c = qemu_tolower(*sp);
        switch (c) {
        default:
                return i;
@@ -394,31 +418,37 @@ cvtstr(
        char            *str,
        size_t          size)
 {
-       const char      *fmt;
-       int             precise;
-
-       precise = ((double)value * 1000 == (double)(int)value * 1000);
+       char            *trim;
+       const char      *suffix;
 
        if (value >= EXABYTES(1)) {
-               fmt = precise ? "%.f EiB" : "%.3f EiB";
-               snprintf(str, size, fmt, TO_EXABYTES(value));
+               suffix = " EiB";
+               snprintf(str, size - 4, "%.3f", TO_EXABYTES(value));
        } else if (value >= PETABYTES(1)) {
-               fmt = precise ? "%.f PiB" : "%.3f PiB";
-               snprintf(str, size, fmt, TO_PETABYTES(value));
+               suffix = " PiB";
+               snprintf(str, size - 4, "%.3f", TO_PETABYTES(value));
        } else if (value >= TERABYTES(1)) {
-               fmt = precise ? "%.f TiB" : "%.3f TiB";
-               snprintf(str, size, fmt, TO_TERABYTES(value));
+               suffix = " TiB";
+               snprintf(str, size - 4, "%.3f", TO_TERABYTES(value));
        } else if (value >= GIGABYTES(1)) {
-               fmt = precise ? "%.f GiB" : "%.3f GiB";
-               snprintf(str, size, fmt, TO_GIGABYTES(value));
+               suffix = " GiB";
+               snprintf(str, size - 4, "%.3f", TO_GIGABYTES(value));
        } else if (value >= MEGABYTES(1)) {
-               fmt = precise ? "%.f MiB" : "%.3f MiB";
-               snprintf(str, size, fmt, TO_MEGABYTES(value));
+               suffix = " MiB";
+               snprintf(str, size - 4, "%.3f", TO_MEGABYTES(value));
        } else if (value >= KILOBYTES(1)) {
-               fmt = precise ? "%.f KiB" : "%.3f KiB";
-               snprintf(str, size, fmt, TO_KILOBYTES(value));
+               suffix = " KiB";
+               snprintf(str, size - 4, "%.3f", TO_KILOBYTES(value));
+       } else {
+               suffix = " bytes";
+               snprintf(str, size - 6, "%f", value);
+       }
+
+       trim = strstr(str, ".000");
+       if (trim) {
+               strcpy(trim, suffix);
        } else {
-               snprintf(str, size, "%f bytes", value);
+               strcat(str, suffix);
        }
 }
 
@@ -458,7 +488,7 @@ timestr(
                        snprintf(ts, size, "%u:%02u.%02u",
                                (unsigned int) MINUTES(tv->tv_sec),
                                (unsigned int) SECONDS(tv->tv_sec),
-                               (unsigned int) usec * 100);
+                               (unsigned int) (usec * 100));
                        return;
                }
                format |= VERBOSE_FIXED_TIME;   /* fallback if hours needed */
@@ -469,9 +499,9 @@ timestr(
                        (unsigned int) HOURS(tv->tv_sec),
                        (unsigned int) MINUTES(tv->tv_sec),
                        (unsigned int) SECONDS(tv->tv_sec),
-                       (unsigned int) usec * 100);
+                       (unsigned int) (usec * 100));
        } else {
-               snprintf(ts, size, "0.%04u sec", (unsigned int) usec * 10000);
+               snprintf(ts, size, "0.%04u sec", (unsigned int) (usec * 10000));
        }
 }