mirror of
https://github.com/qemu/qemu.git
synced 2024-11-28 14:24:02 +08:00
custom option parsing to have same behavior on all OSes
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@805 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
b939777cec
commit
cd6f11693a
273
vl.c
273
vl.c
@ -23,7 +23,6 @@
|
||||
*/
|
||||
#include "vl.h"
|
||||
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
@ -1908,6 +1907,7 @@ void help(void)
|
||||
"-initrd file use 'file' as initial ram disk\n"
|
||||
"\n"
|
||||
"Debug/Expert options:\n"
|
||||
"-S freeze CPU at startup (use 'c' to start execution)\n"
|
||||
"-s wait gdb connection to port %d\n"
|
||||
"-p port change gdb connection port\n"
|
||||
"-d item1,... output log to %s (use -d ? for a list of log items)\n"
|
||||
@ -1937,29 +1937,85 @@ void help(void)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
struct option long_options[] = {
|
||||
{ "initrd", 1, NULL, 0, },
|
||||
{ "hda", 1, NULL, 0, },
|
||||
{ "hdb", 1, NULL, 0, },
|
||||
{ "snapshot", 0, NULL, 0, },
|
||||
{ "hdachs", 1, NULL, 0, },
|
||||
{ "nographic", 0, NULL, 0, },
|
||||
{ "kernel", 1, NULL, 0, },
|
||||
{ "append", 1, NULL, 0, },
|
||||
{ "tun-fd", 1, NULL, 0, },
|
||||
{ "hdc", 1, NULL, 0, },
|
||||
{ "hdd", 1, NULL, 0, },
|
||||
{ "cdrom", 1, NULL, 0, },
|
||||
{ "boot", 1, NULL, 0, },
|
||||
{ "fda", 1, NULL, 0, },
|
||||
{ "fdb", 1, NULL, 0, },
|
||||
{ "no-code-copy", 0, NULL, 0 },
|
||||
{ "nics", 1, NULL, 0 },
|
||||
{ "macaddr", 1, NULL, 0 },
|
||||
{ "user-net", 0, NULL, 0 },
|
||||
{ "dummy-net", 0, NULL, 0 },
|
||||
{ "enable-audio", 0, NULL, 0 },
|
||||
{ NULL, 0, NULL, 0 },
|
||||
#define HAS_ARG 0x0001
|
||||
|
||||
enum {
|
||||
QEMU_OPTION_h,
|
||||
|
||||
QEMU_OPTION_fda,
|
||||
QEMU_OPTION_fdb,
|
||||
QEMU_OPTION_hda,
|
||||
QEMU_OPTION_hdb,
|
||||
QEMU_OPTION_hdc,
|
||||
QEMU_OPTION_hdd,
|
||||
QEMU_OPTION_cdrom,
|
||||
QEMU_OPTION_boot,
|
||||
QEMU_OPTION_snapshot,
|
||||
QEMU_OPTION_m,
|
||||
QEMU_OPTION_nographic,
|
||||
QEMU_OPTION_enable_audio,
|
||||
|
||||
QEMU_OPTION_nics,
|
||||
QEMU_OPTION_macaddr,
|
||||
QEMU_OPTION_n,
|
||||
QEMU_OPTION_tun_fd,
|
||||
QEMU_OPTION_user_net,
|
||||
QEMU_OPTION_dummy_net,
|
||||
|
||||
QEMU_OPTION_kernel,
|
||||
QEMU_OPTION_append,
|
||||
QEMU_OPTION_initrd,
|
||||
|
||||
QEMU_OPTION_S,
|
||||
QEMU_OPTION_s,
|
||||
QEMU_OPTION_p,
|
||||
QEMU_OPTION_d,
|
||||
QEMU_OPTION_hdachs,
|
||||
QEMU_OPTION_L,
|
||||
QEMU_OPTION_no_code_copy,
|
||||
};
|
||||
|
||||
typedef struct QEMUOption {
|
||||
const char *name;
|
||||
int flags;
|
||||
int index;
|
||||
} QEMUOption;
|
||||
|
||||
const QEMUOption qemu_options[] = {
|
||||
{ "h", 0, QEMU_OPTION_h },
|
||||
|
||||
{ "fda", HAS_ARG, QEMU_OPTION_fda },
|
||||
{ "fdb", HAS_ARG, QEMU_OPTION_fdb },
|
||||
{ "hda", HAS_ARG, QEMU_OPTION_hda },
|
||||
{ "hdb", HAS_ARG, QEMU_OPTION_hdb },
|
||||
{ "hdc", HAS_ARG, QEMU_OPTION_hdc },
|
||||
{ "hdd", HAS_ARG, QEMU_OPTION_hdd },
|
||||
{ "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
|
||||
{ "boot", HAS_ARG, QEMU_OPTION_boot },
|
||||
{ "snapshot", 0, QEMU_OPTION_snapshot },
|
||||
{ "m", HAS_ARG, QEMU_OPTION_m },
|
||||
{ "nographic", 0, QEMU_OPTION_nographic },
|
||||
{ "enable-audio", 0, QEMU_OPTION_enable_audio },
|
||||
|
||||
{ "nics", HAS_ARG, QEMU_OPTION_nics},
|
||||
{ "macaddr", HAS_ARG, QEMU_OPTION_macaddr},
|
||||
{ "n", HAS_ARG, QEMU_OPTION_d },
|
||||
{ "tun-fd", HAS_ARG, QEMU_OPTION_tun_fd },
|
||||
{ "user-net", 0, QEMU_OPTION_user_net },
|
||||
{ "dummy-net", 0, QEMU_OPTION_dummy_net },
|
||||
|
||||
{ "kernel", HAS_ARG, QEMU_OPTION_kernel },
|
||||
{ "append", HAS_ARG, QEMU_OPTION_append },
|
||||
{ "initrd", HAS_ARG, QEMU_OPTION_initrd },
|
||||
|
||||
{ "S", 0, QEMU_OPTION_S },
|
||||
{ "s", 0, QEMU_OPTION_s },
|
||||
{ "p", HAS_ARG, QEMU_OPTION_p },
|
||||
{ "d", HAS_ARG, QEMU_OPTION_d },
|
||||
{ "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
|
||||
{ "L", HAS_ARG, QEMU_OPTION_L },
|
||||
{ "no-code-copy", 0, QEMU_OPTION_no_code_copy },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
|
||||
@ -1980,7 +2036,7 @@ int main(int argc, char **argv)
|
||||
#ifdef CONFIG_GDBSTUB
|
||||
int use_gdbstub, gdbstub_port;
|
||||
#endif
|
||||
int c, i, long_index, has_cdrom;
|
||||
int i, has_cdrom;
|
||||
int snapshot, linux_boot;
|
||||
CPUState *env;
|
||||
const char *initrd_filename;
|
||||
@ -1991,7 +2047,9 @@ int main(int argc, char **argv)
|
||||
int start_emulation = 1;
|
||||
uint8_t macaddr[6];
|
||||
int net_if_type, nb_tun_fds, tun_fds[MAX_NICS];
|
||||
|
||||
int optind;
|
||||
const char *r, *optarg;
|
||||
|
||||
#if !defined(CONFIG_SOFTMMU)
|
||||
/* we never want that malloc() uses mmap() */
|
||||
mallopt(M_MMAP_THRESHOLD, 4096 * 1024);
|
||||
@ -2026,27 +2084,53 @@ int main(int argc, char **argv)
|
||||
macaddr[4] = 0x34;
|
||||
macaddr[5] = 0x56;
|
||||
|
||||
|
||||
optind = 1;
|
||||
for(;;) {
|
||||
c = getopt_long_only(argc, argv, "hm:d:n:sp:L:S", long_options, &long_index);
|
||||
if (c == -1)
|
||||
if (optind >= argc)
|
||||
break;
|
||||
switch(c) {
|
||||
case 0:
|
||||
switch(long_index) {
|
||||
case 0:
|
||||
r = argv[optind];
|
||||
if (r[0] != '-') {
|
||||
hd_filename[0] = argv[optind++];
|
||||
} else {
|
||||
const QEMUOption *popt;
|
||||
|
||||
optind++;
|
||||
popt = qemu_options;
|
||||
for(;;) {
|
||||
if (!popt->name) {
|
||||
fprintf(stderr, "%s: invalid option -- '%s'\n",
|
||||
argv[0], r);
|
||||
exit(1);
|
||||
}
|
||||
if (!strcmp(popt->name, r + 1))
|
||||
break;
|
||||
popt++;
|
||||
}
|
||||
if (popt->flags & HAS_ARG) {
|
||||
if (optind >= argc) {
|
||||
fprintf(stderr, "%s: option '%s' requires an argument\n",
|
||||
argv[0], r);
|
||||
exit(1);
|
||||
}
|
||||
optarg = argv[optind++];
|
||||
} else {
|
||||
optarg = NULL;
|
||||
}
|
||||
|
||||
switch(popt->index) {
|
||||
case QEMU_OPTION_initrd:
|
||||
initrd_filename = optarg;
|
||||
break;
|
||||
case 1:
|
||||
case QEMU_OPTION_hda:
|
||||
hd_filename[0] = optarg;
|
||||
break;
|
||||
case 2:
|
||||
case QEMU_OPTION_hdb:
|
||||
hd_filename[1] = optarg;
|
||||
break;
|
||||
case 3:
|
||||
case QEMU_OPTION_snapshot:
|
||||
snapshot = 1;
|
||||
break;
|
||||
case 4:
|
||||
case QEMU_OPTION_hdachs:
|
||||
{
|
||||
const char *p;
|
||||
p = optarg;
|
||||
@ -2065,16 +2149,16 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
case QEMU_OPTION_nographic:
|
||||
nographic = 1;
|
||||
break;
|
||||
case 6:
|
||||
case QEMU_OPTION_kernel:
|
||||
kernel_filename = optarg;
|
||||
break;
|
||||
case 7:
|
||||
case QEMU_OPTION_append:
|
||||
kernel_cmdline = optarg;
|
||||
break;
|
||||
case 8:
|
||||
case QEMU_OPTION_tun_fd:
|
||||
{
|
||||
const char *p;
|
||||
int fd;
|
||||
@ -2089,18 +2173,18 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
case QEMU_OPTION_hdc:
|
||||
hd_filename[2] = optarg;
|
||||
has_cdrom = 0;
|
||||
break;
|
||||
case 10:
|
||||
case QEMU_OPTION_hdd:
|
||||
hd_filename[3] = optarg;
|
||||
break;
|
||||
case 11:
|
||||
case QEMU_OPTION_cdrom:
|
||||
hd_filename[2] = optarg;
|
||||
has_cdrom = 1;
|
||||
break;
|
||||
case 12:
|
||||
case QEMU_OPTION_boot:
|
||||
boot_device = optarg[0];
|
||||
if (boot_device != 'a' && boot_device != 'b' &&
|
||||
boot_device != 'c' && boot_device != 'd') {
|
||||
@ -2108,23 +2192,23 @@ int main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 13:
|
||||
case QEMU_OPTION_fda:
|
||||
fd_filename[0] = optarg;
|
||||
break;
|
||||
case 14:
|
||||
case QEMU_OPTION_fdb:
|
||||
fd_filename[1] = optarg;
|
||||
break;
|
||||
case 15:
|
||||
case QEMU_OPTION_no_code_copy:
|
||||
code_copy_enabled = 0;
|
||||
break;
|
||||
case 16:
|
||||
case QEMU_OPTION_nics:
|
||||
nb_nics = atoi(optarg);
|
||||
if (nb_nics < 0 || nb_nics > MAX_NICS) {
|
||||
fprintf(stderr, "qemu: invalid number of network interfaces\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 17:
|
||||
case QEMU_OPTION_macaddr:
|
||||
{
|
||||
const char *p;
|
||||
int i;
|
||||
@ -2145,70 +2229,65 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 18:
|
||||
case QEMU_OPTION_user_net:
|
||||
net_if_type = NET_IF_USER;
|
||||
break;
|
||||
case 19:
|
||||
case QEMU_OPTION_dummy_net:
|
||||
net_if_type = NET_IF_DUMMY;
|
||||
break;
|
||||
case 20:
|
||||
case QEMU_OPTION_enable_audio:
|
||||
audio_enabled = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
help();
|
||||
break;
|
||||
case 'm':
|
||||
ram_size = atoi(optarg) * 1024 * 1024;
|
||||
if (ram_size <= 0)
|
||||
case QEMU_OPTION_h:
|
||||
help();
|
||||
if (ram_size > PHYS_RAM_MAX_SIZE) {
|
||||
fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n",
|
||||
PHYS_RAM_MAX_SIZE / (1024 * 1024));
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
{
|
||||
int mask;
|
||||
CPULogItem *item;
|
||||
|
||||
mask = cpu_str_to_log_mask(optarg);
|
||||
if (!mask) {
|
||||
printf("Log items (comma separated):\n");
|
||||
break;
|
||||
case QEMU_OPTION_m:
|
||||
ram_size = atoi(optarg) * 1024 * 1024;
|
||||
if (ram_size <= 0)
|
||||
help();
|
||||
if (ram_size > PHYS_RAM_MAX_SIZE) {
|
||||
fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n",
|
||||
PHYS_RAM_MAX_SIZE / (1024 * 1024));
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case QEMU_OPTION_d:
|
||||
{
|
||||
int mask;
|
||||
CPULogItem *item;
|
||||
|
||||
mask = cpu_str_to_log_mask(optarg);
|
||||
if (!mask) {
|
||||
printf("Log items (comma separated):\n");
|
||||
for(item = cpu_log_items; item->mask != 0; item++) {
|
||||
printf("%-10s %s\n", item->name, item->help);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
cpu_set_log(mask);
|
||||
}
|
||||
cpu_set_log(mask);
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
pstrcpy(network_script, sizeof(network_script), optarg);
|
||||
break;
|
||||
break;
|
||||
case QEMU_OPTION_n:
|
||||
pstrcpy(network_script, sizeof(network_script), optarg);
|
||||
break;
|
||||
#ifdef CONFIG_GDBSTUB
|
||||
case 's':
|
||||
use_gdbstub = 1;
|
||||
break;
|
||||
case 'p':
|
||||
gdbstub_port = atoi(optarg);
|
||||
break;
|
||||
case QEMU_OPTION_s:
|
||||
use_gdbstub = 1;
|
||||
break;
|
||||
case QEMU_OPTION_p:
|
||||
gdbstub_port = atoi(optarg);
|
||||
break;
|
||||
#endif
|
||||
case 'L':
|
||||
bios_dir = optarg;
|
||||
break;
|
||||
case 'S':
|
||||
start_emulation = 0;
|
||||
break;
|
||||
case QEMU_OPTION_L:
|
||||
bios_dir = optarg;
|
||||
break;
|
||||
case QEMU_OPTION_S:
|
||||
start_emulation = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc) {
|
||||
hd_filename[0] = argv[optind++];
|
||||
}
|
||||
|
||||
linux_boot = (kernel_filename != NULL);
|
||||
|
||||
if (!linux_boot && hd_filename[0] == '\0' && hd_filename[2] == '\0' &&
|
||||
|
Loading…
Reference in New Issue
Block a user