⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 monitor.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        }        p++;    } else {        while (*p != '\0' && !isspace(*p)) {            if ((q - buf) < buf_size - 1) {                *q++ = *p;            }            p++;        }    }    *q = '\0';    *pp = p;    return 0;}static int default_fmt_format = 'x';static int default_fmt_size = 4;#define MAX_ARGS 16static void monitor_handle_command(const char *cmdline){    const char *p, *pstart, *typestr;    char *q;    int c, nb_args, len, i, has_arg;    term_cmd_t *cmd;    char cmdname[256];    char buf[1024];    void *str_allocated[MAX_ARGS];    void *args[MAX_ARGS];#ifdef DEBUG    term_printf("command='%s'\n", cmdline);#endif        /* extract the command name */    p = cmdline;    q = cmdname;    while (isspace(*p))        p++;    if (*p == '\0')        return;    pstart = p;    while (*p != '\0' && *p != '/' && !isspace(*p))        p++;    len = p - pstart;    if (len > sizeof(cmdname) - 1)        len = sizeof(cmdname) - 1;    memcpy(cmdname, pstart, len);    cmdname[len] = '\0';        /* find the command */    for(cmd = term_cmds; cmd->name != NULL; cmd++) {        if (compare_cmd(cmdname, cmd->name))             goto found;    }    term_printf("unknown command: '%s'\n", cmdname);    return; found:    for(i = 0; i < MAX_ARGS; i++)        str_allocated[i] = NULL;        /* parse the parameters */    typestr = cmd->args_type;    nb_args = 0;    for(;;) {        c = *typestr;        if (c == '\0')            break;        typestr++;        switch(c) {        case 'F':        case 'B':        case 's':            {                int ret;                char *str;                                while (isspace(*p))                     p++;                if (*typestr == '?') {                    typestr++;                    if (*p == '\0') {                        /* no optional string: NULL argument */                        str = NULL;                        goto add_str;                    }                }                ret = get_str(buf, sizeof(buf), &p);                if (ret < 0) {                    switch(c) {                    case 'F':                        term_printf("%s: filename expected\n", cmdname);                        break;                    case 'B':                        term_printf("%s: block device name expected\n", cmdname);                        break;                    default:                        term_printf("%s: string expected\n", cmdname);                        break;                    }                    goto fail;                }                str = qemu_malloc(strlen(buf) + 1);                strcpy(str, buf);                str_allocated[nb_args] = str;            add_str:                if (nb_args >= MAX_ARGS) {                error_args:                    term_printf("%s: too many arguments\n", cmdname);                    goto fail;                }                args[nb_args++] = str;            }            break;        case '/':            {                int count, format, size;                                while (isspace(*p))                    p++;                if (*p == '/') {                    /* format found */                    p++;                    count = 1;                    if (isdigit(*p)) {                        count = 0;                        while (isdigit(*p)) {                            count = count * 10 + (*p - '0');                            p++;                        }                    }                    size = -1;                    format = -1;                    for(;;) {                        switch(*p) {                        case 'o':                        case 'd':                        case 'u':                        case 'x':                        case 'i':                        case 'c':                            format = *p++;                            break;                        case 'b':                            size = 1;                            p++;                            break;                        case 'h':                            size = 2;                            p++;                            break;                        case 'w':                            size = 4;                            p++;                            break;                        case 'g':                        case 'L':                            size = 8;                            p++;                            break;                        default:                            goto next;                        }                    }                next:                    if (*p != '\0' && !isspace(*p)) {                        term_printf("invalid char in format: '%c'\n", *p);                        goto fail;                    }                    if (format < 0)                        format = default_fmt_format;                    if (format != 'i') {                        /* for 'i', not specifying a size gives -1 as size */                        if (size < 0)                            size = default_fmt_size;                    }                    default_fmt_size = size;                    default_fmt_format = format;                } else {                    count = 1;                    format = default_fmt_format;                    if (format != 'i') {                        size = default_fmt_size;                    } else {                        size = -1;                    }                }                if (nb_args + 3 > MAX_ARGS)                    goto error_args;                args[nb_args++] = (void*)count;                args[nb_args++] = (void*)format;                args[nb_args++] = (void*)size;            }            break;        case 'i':        case 'l':            {                target_long val;                while (isspace(*p))                     p++;                if (*typestr == '?' || *typestr == '.') {                    typestr++;                    if (*typestr == '?') {                        if (*p == '\0')                            has_arg = 0;                        else                            has_arg = 1;                    } else {                        if (*p == '.') {                            p++;                            while (isspace(*p))                                 p++;                            has_arg = 1;                        } else {                            has_arg = 0;                        }                    }                    if (nb_args >= MAX_ARGS)                        goto error_args;                    args[nb_args++] = (void *)has_arg;                    if (!has_arg) {                        if (nb_args >= MAX_ARGS)                            goto error_args;                        val = -1;                        goto add_num;                    }                }                if (get_expr(&val, &p))                    goto fail;            add_num:                if (c == 'i') {                    if (nb_args >= MAX_ARGS)                        goto error_args;                    args[nb_args++] = (void *)(int)val;                } else {                    if ((nb_args + 1) >= MAX_ARGS)                        goto error_args;#if TARGET_LONG_BITS == 64                    args[nb_args++] = (void *)(int)((val >> 32) & 0xffffffff);#else                    args[nb_args++] = (void *)0;#endif                    args[nb_args++] = (void *)(int)(val & 0xffffffff);                }            }            break;        case '-':            {                int has_option;                /* option */                                c = *typestr++;                if (c == '\0')                    goto bad_type;                while (isspace(*p))                     p++;                has_option = 0;                if (*p == '-') {                    p++;                    if (*p != c) {                        term_printf("%s: unsupported option -%c\n",                                     cmdname, *p);                        goto fail;                    }                    p++;                    has_option = 1;                }                if (nb_args >= MAX_ARGS)                    goto error_args;                args[nb_args++] = (void *)has_option;            }            break;        default:        bad_type:            term_printf("%s: unknown type '%c'\n", cmdname, c);            goto fail;        }    }    /* check that all arguments were parsed */    while (isspace(*p))        p++;    if (*p != '\0') {        term_printf("%s: extraneous characters at the end of line\n",                     cmdname);        goto fail;    }    switch(nb_args) {    case 0:        cmd->handler();        break;    case 1:        cmd->handler(args[0]);        break;    case 2:        cmd->handler(args[0], args[1]);        break;    case 3:        cmd->handler(args[0], args[1], args[2]);        break;    case 4:        cmd->handler(args[0], args[1], args[2], args[3]);        break;    case 5:        cmd->handler(args[0], args[1], args[2], args[3], args[4]);        break;    case 6:        cmd->handler(args[0], args[1], args[2], args[3], args[4], args[5]);        break;    default:        term_printf("unsupported number of arguments: %d\n", nb_args);        goto fail;    } fail:    for(i = 0; i < MAX_ARGS; i++)        qemu_free(str_allocated[i]);    return;}static void cmd_completion(const char *name, const char *list){    const char *p, *pstart;    char cmd[128];    int len;    p = list;    for(;;) {        pstart = p;        p = strchr(p, '|');        if (!p)            p = pstart + strlen(pstart);        len = p - pstart;        if (len > sizeof(cmd) - 2)            len = sizeof(cmd) - 2;        memcpy(cmd, pstart, len);        cmd[len] = '\0';        if (name[0] == '\0' || !strncmp(name, cmd, strlen(name))) {            add_completion(cmd);        }        if (*p == '\0')            break;        p++;    }}static void file_completion(const char *input){    DIR *ffs;    struct dirent *d;    char path[1024];    char file[1024], file_prefix[1024];    int input_path_len;    const char *p;    p = strrchr(input, '/');     if (!p) {        input_path_len = 0;        pstrcpy(file_prefix, sizeof(file_prefix), input);        strcpy(path, ".");    } else {        input_path_len = p - input + 1;        memcpy(path, input, input_path_len);        if (input_path_len > sizeof(path) - 1)            input_path_len = sizeof(path) - 1;        path[input_path_len] = '\0';        pstrcpy(file_prefix, sizeof(file_prefix), p + 1);    }#ifdef DEBUG_COMPLETION    term_printf("input='%s' path='%s' prefix='%s'\n", input, path, file_prefix);#endif    ffs = opendir(path);    if (!ffs)        return;    for(;;) {        struct stat sb;        d = readdir(ffs);        if (!d)            break;        if (strstart(d->d_name, file_prefix, NULL)) {            memcpy(file, input, input_path_len);            strcpy(file + input_path_len, d->d_name);            /* stat the file to find out if it's a directory.             * In that case add a slash to speed up typing long paths             */            stat(file, &sb);            if(S_ISDIR(sb.st_mode))                strcat(file, "/");            add_completion(file);        }    }    closedir(ffs);}static void block_completion_it(void *opaque, const char *name){    const char *input = opaque;    if (input[0] == '\0' ||        !strncmp(name, (char *)input, strlen(input))) {        add_completion(name);    }}/* NOTE: this parser is an approximate form of the real command parser */static void parse_cmdline(const char *cmdline,                         int *pnb_args, char **args){    const char *p;    int nb_args, ret;    char buf[1024];    p = cmdline;    nb_args = 0;    for(;;) {        while (isspace(*p))            p++;        if (*p == '\0')            break;        if (nb_args >= MAX_ARGS)            break;        ret = get_str(buf, sizeof(buf), &p);        args[nb_args] = qemu_strdup(buf);        nb_args++;        if (ret < 0)            break;    }    *pnb_args = nb_args;}void readline_find_completion(const char *cmdline){    const char *cmdname;    char *args[MAX_ARGS];    int nb_args, i, len;    const char *ptype, *str;    term_cmd_t *cmd;    parse_cmdline(cmdline, &nb_args, args);#ifdef DEBUG_COMPLETION    for(i = 0; i < nb_args; i++) {        term_printf("arg%d = '%s'\n", i, (char *)args[i]);    }#endif    /* if the line ends with a space, it means we want to complete the       next arg */    len = strlen(cmdline);    if (len > 0 && isspace(cmdline[len - 1])) {        if (nb_args >= MAX_ARGS)            return;        args[nb_args++] = qemu_strdup("");    }    if (nb_args <= 1) {        /* command completion */        if (nb_args == 0)            cmdname = "";        else            cmdname = args[0];        completion_index = strlen(cmdname);        for(cmd = term_cmds; cmd->name != NULL; cmd++) {            cmd_completion(cmdname, cmd->name);        }    } else {        /* find the command */        for(cmd = term_cmds; cmd->name != NULL; cmd++) {            if (compare_cmd(args[0], cmd->name))                goto found;        }        return;    found:        ptype = cmd->args_type;        for(i = 0; i < nb_args - 2; i++) {            if (*ptype != '\0') {                ptype++;                while (*ptype == '?')                    ptype++;            }        }        str = args[nb_args - 1];        switch(*ptype) {        case 'F':            /* file completion */            completion_index = strlen(str);            file_completion(str);            break;        case 'B':            /* block device name completion */            completion_index = strlen(str);            bdrv_iterate(block_completion_it, (void *)str);            break;        case 's':            /* XXX: more generic ? */            if (!strcmp(cmd->name, "info")) {                completion_index = strlen(str);                for(cmd = info_cmds; cmd->name != NULL; cmd++) {                    cmd_completion(str, cmd->name);                }            }            break;        default:            break;        }    }    for(i = 0; i < nb_args; i++)        qemu_free(args[i]);}static int term_can_read(void *opaque){    return 128;}static void term_read(void *opaque, const uint8_t *buf, int size){    int i;    for(i = 0; i < size; i++)        readline_handle_byte(buf[i]);}static void monitor_start_input(void);static void monitor_handle_command1(void *opaque, const char *cmdline){    monitor_handle_command(cmdline);    monitor_start_input();}static void monitor_start_input(void){    readline_start("(qemu) ", 0, monitor_handle_command1, NULL);}void monitor_init(CharDriverState *hd, int show_banner){    monitor_hd = hd;    if (show_banner) {        term_printf("QEMU %s monitor - type 'help' for more information\n",                    QEMU_VERSION);    }    qemu_chr_add_read_handler(hd, term_can_read, term_read, NULL);    monitor_start_input();}/* XXX: use threads ? *//* modal monitor readline */static int monitor_readline_started;static char *monitor_readline_buf;static int monitor_readline_buf_size;static void monitor_readline_cb(void *opaque, const char *input){    pstrcpy(monitor_readline_buf, monitor_readline_buf_size, input);    monitor_readline_started = 0;}void monitor_readline(const char *prompt, int is_password,                      char *buf, int buf_size){    if (is_password) {        qemu_chr_send_event(monitor_hd, CHR_EVENT_FOCUS);    }    readline_start(prompt, is_password, monitor_readline_cb, NULL);    monitor_readline_buf = buf;    monitor_readline_buf_size = buf_size;    monitor_readline_started = 1;    while (monitor_readline_started) {        main_loop_wait(10);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -