qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] Enhance monitor change command


From: Anthony Liguori
Subject: [Qemu-devel] [PATCH] Enhance monitor change command
Date: Sat, 03 Mar 2007 22:12:29 -0600
User-agent: Thunderbird 1.5.0.9 (X11/20070103)

Howdy,

The following patch allows the change monitor command to be used with vnc, serial, and parallel devices. It depends on my previously posted patches.

The patch implements:

1) A vnc "null" display
2) The ability to reopen character devices
3) Appropriate tab expansions for devices

This patch is quite useful for management tools as it allows much more flexibility in allowing the user to configure running instances.

Regards,

Anthony Liguori
diff -r 6b23d9afec55 console.c
--- a/console.c Sat Mar 03 21:35:55 2007 -0600
+++ b/console.c Sat Mar 03 21:42:27 2007 -0600
@@ -1155,16 +1155,12 @@ int is_graphic_console(void)
     return !active_console->text_console;
 }
 
-CharDriverState *text_console_init(DisplayState *ds)
-{
-    CharDriverState *chr;
+CharDriverState *text_console_init(CharDriverState *chr, DisplayState *ds)
+{
     TextConsole *s;
     int i,j;
     static int color_inited;
 
-    chr = qemu_mallocz(sizeof(CharDriverState));
-    if (!chr)
-        return NULL;
     s = new_console(ds, 1);
     if (!s) {
         free(chr);
diff -r 6b23d9afec55 monitor.c
--- a/monitor.c Sat Mar 03 21:35:55 2007 -0600
+++ b/monitor.c Sat Mar 03 21:58:55 2007 -0600
@@ -372,7 +372,7 @@ static void do_eject(int force, const ch
     eject_device(bs, force);
 }
 
-static void do_change(const char *device, const char *filename)
+static void do_change_block(const char *device, const char *filename)
 {
     BlockDriverState *bs;
     int i;
@@ -395,6 +395,33 @@ static void do_change(const char *device
             term_printf("invalid password\n");
         }
     }
+}
+
+static void do_change(const char *device, const char *target)
+{
+    const char *p;
+
+    if (strcmp(device, "vnc") == 0) {
+       if (vnc_display_open(NULL, target) == -1)
+           term_printf("could not start VNC server on %s\n", target);
+    } else if (strstart(device, "serial", &p)) {
+       int index = atoi(p);
+       if (index < 0 || index >= MAX_SERIAL_PORTS) {
+           term_printf("Invalid serial device %d\n", index);
+           return;
+       }
+       if (qemu_chr_open2(serial_hds[index], target) == NULL)
+           term_printf("Could not reopen serial device\n");
+    } else if (strstart(device, "parallel", &p)) {
+       int index = atoi(p);
+       if (index < 0 || index >= MAX_PARALLEL_PORTS) {
+           term_printf("Invalid parallel device %d\n", index);
+           return;
+       }
+       if (qemu_chr_open2(parallel_hds[index], target) == NULL)
+           term_printf("Could not reopen serial device\n");
+    } else
+       do_change_block(device, target);
 }
 
 static void do_screen_dump(const char *filename)
@@ -1205,8 +1232,8 @@ static term_cmd_t term_cmds[] = {
       "", "quit the emulator" },
     { "eject", "-fB", do_eject,
       "[-f] device", "eject a removable media (use -f to force it)" },
-    { "change", "BF", do_change,
-      "device filename", "change a removable media" },
+    { "change", "DF", do_change,
+      "device filename", "change a device target" },
     { "screendump", "F", do_screen_dump, 
       "filename", "save screen into PPM image 'filename'" },
     { "log", "s", do_log,
@@ -1988,6 +2015,7 @@ static void monitor_handle_command(const
         switch(c) {
         case 'F':
         case 'B':
+       case 'D':
         case 's':
             {
                 int ret;
@@ -2012,6 +2040,9 @@ static void monitor_handle_command(const
                     case 'B':
                         term_printf("%s: block device name expected\n", 
cmdname);
                         break;
+                   case 'D':
+                       term_printf("%s: device name expected\n", cmdname);
+                       break;
                     default:
                         term_printf("%s: string expected\n", cmdname);
                         break;
@@ -2312,7 +2343,7 @@ static void file_completion(const char *
     closedir(ffs);
 }
 
-static void block_completion_it(void *opaque, const char *name)
+static void device_completion_it(void *opaque, const char *name)
 {
     const char *input = opaque;
 
@@ -2320,6 +2351,26 @@ static void block_completion_it(void *op
         !strncmp(name, (char *)input, strlen(input))) {
         add_completion(name);
     }
+}
+
+static void device_iterate(void (*it)(void *opaque, const char *name), void 
*opaque)
+{
+    char buf[128];
+    int i;
+
+    bdrv_iterate(it, opaque);
+
+    for (i = 0; i < MAX_SERIAL_PORTS; i++) {
+       snprintf(buf, sizeof(buf), "serial%d", i);
+       it(opaque, buf);
+    }
+
+    for (i = 0; i < MAX_SERIAL_PORTS; i++) {
+       snprintf(buf, sizeof(buf), "parallel%d", i);
+       it(opaque, buf);
+    }
+
+    it(opaque, "vnc");
 }
 
 /* NOTE: this parser is an approximate form of the real command parser */
@@ -2408,8 +2459,13 @@ void readline_find_completion(const char
         case 'B':
             /* block device name completion */
             completion_index = strlen(str);
-            bdrv_iterate(block_completion_it, (void *)str);
-            break;
+            bdrv_iterate(device_completion_it, (void *)str);
+            break;
+       case 'D':
+           /* device name completion */
+           completion_index = strlen(str);
+           device_iterate(device_completion_it, (void *)str);
+           break;
         case 's':
             /* XXX: more generic ? */
             if (!strcmp(cmd->name, "info")) {
diff -r 6b23d9afec55 vl.c
--- a/vl.c      Sat Mar 03 21:35:55 2007 -0600
+++ b/vl.c      Sat Mar 03 22:01:35 2007 -0600
@@ -1219,13 +1219,8 @@ static int null_chr_write(CharDriverStat
     return len;
 }
 
-static CharDriverState *qemu_chr_open_null(void)
-{
-    CharDriverState *chr;
-
-    chr = qemu_mallocz(sizeof(CharDriverState));
-    if (!chr)
-        return NULL;
+static CharDriverState *qemu_chr_open_null(CharDriverState *chr)
+{
     chr->chr_write = null_chr_write;
     return chr;
 }
@@ -1587,15 +1582,16 @@ static void fd_chr_update_read_handler(C
     }
 }
 
+static void fd_chr_close(CharDriverState *chr)
+{
+    free(chr->opaque);
+}
+
 /* open a character device to a unix fd */
-static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
-{
-    CharDriverState *chr;
+static CharDriverState *qemu_chr_open_fd(CharDriverState *chr, int fd_in, int 
fd_out)
+{
     FDCharDriver *s;
 
-    chr = qemu_mallocz(sizeof(CharDriverState));
-    if (!chr)
-        return NULL;
     s = qemu_mallocz(sizeof(FDCharDriver));
     if (!s) {
         free(chr);
@@ -1606,23 +1602,24 @@ static CharDriverState *qemu_chr_open_fd
     chr->opaque = s;
     chr->chr_write = fd_chr_write;
     chr->chr_update_read_handler = fd_chr_update_read_handler;
+    chr->chr_close = fd_chr_close;
 
     qemu_chr_reset(chr);
 
     return chr;
 }
 
-static CharDriverState *qemu_chr_open_file_out(const char *file_out)
+static CharDriverState *qemu_chr_open_file_out(CharDriverState *chr, const 
char *file_out)
 {
     int fd_out;
 
     fd_out = open(file_out, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666);
     if (fd_out < 0)
         return NULL;
-    return qemu_chr_open_fd(-1, fd_out);
-}
-
-static CharDriverState *qemu_chr_open_pipe(const char *filename)
+    return qemu_chr_open_fd(chr, -1, fd_out);
+}
+
+static CharDriverState *qemu_chr_open_pipe(CharDriverState *chr, const char 
*filename)
 {
     int fd_in, fd_out;
     char filename_in[256], filename_out[256];
@@ -1640,7 +1637,7 @@ static CharDriverState *qemu_chr_open_pi
         if (fd_in < 0)
             return NULL;
     }
-    return qemu_chr_open_fd(fd_in, fd_out);
+    return qemu_chr_open_fd(chr, fd_in, fd_out);
 }
 
 
@@ -1726,13 +1723,11 @@ static void term_init(void)
     fcntl(0, F_SETFL, O_NONBLOCK);
 }
 
-static CharDriverState *qemu_chr_open_stdio(void)
-{
-    CharDriverState *chr;
-
+static CharDriverState *qemu_chr_open_stdio(CharDriverState *chr)
+{
     if (stdio_nb_clients >= STDIO_MAX_CLIENTS)
         return NULL;
-    chr = qemu_chr_open_fd(0, 1);
+    chr = qemu_chr_open_fd(chr, 0, 1);
     qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, chr);
     stdio_nb_clients++;
     term_init();
@@ -1741,7 +1736,7 @@ static CharDriverState *qemu_chr_open_st
 }
 
 #if defined(__linux__)
-static CharDriverState *qemu_chr_open_pty(void)
+static CharDriverState *qemu_chr_open_pty(CharDriverState *chr)
 {
     struct termios tty;
     char slave_name[1024];
@@ -1760,7 +1755,7 @@ static CharDriverState *qemu_chr_open_pt
     tcsetattr (master_fd, TCSAFLUSH, &tty);
 
     fprintf(stderr, "char device redirected to %s\n", slave_name);
-    return qemu_chr_open_fd(master_fd, master_fd);
+    return qemu_chr_open_fd(chr, master_fd, master_fd);
 }
 
 static void tty_serial_init(int fd, int speed, 
@@ -1880,9 +1875,8 @@ static int tty_serial_ioctl(CharDriverSt
     return 0;
 }
 
-static CharDriverState *qemu_chr_open_tty(const char *filename)
-{
-    CharDriverState *chr;
+static CharDriverState *qemu_chr_open_tty(CharDriverState *chr, const char 
*filename)
+{
     int fd;
 
     fd = open(filename, O_RDWR | O_NONBLOCK);
@@ -1890,7 +1884,7 @@ static CharDriverState *qemu_chr_open_tt
         return NULL;
     fcntl(fd, F_SETFL, O_NONBLOCK);
     tty_serial_init(fd, 115200, 'N', 8, 1);
-    chr = qemu_chr_open_fd(fd, fd);
+    chr = qemu_chr_open_fd(chr, fd, fd);
     if (!chr)
         return NULL;
     chr->chr_ioctl = tty_serial_ioctl;
@@ -2002,9 +1996,8 @@ static void pp_close(CharDriverState *ch
     qemu_free(drv);
 }
 
-static CharDriverState *qemu_chr_open_pp(const char *filename)
-{
-    CharDriverState *chr;
+static CharDriverState *qemu_chr_open_pp(CharDriverState *chr, const char 
*filename)
+{
     ParallelCharDriver *drv;
     int fd;
 
@@ -2025,12 +2018,6 @@ static CharDriverState *qemu_chr_open_pp
     drv->fd = fd;
     drv->mode = IEEE1284_MODE_COMPAT;
 
-    chr = qemu_mallocz(sizeof(CharDriverState));
-    if (!chr) {
-       qemu_free(drv);
-        close(fd);
-        return NULL;
-    }
     chr->chr_write = null_chr_write;
     chr->chr_ioctl = pp_ioctl;
     chr->chr_close = pp_close;
@@ -2249,14 +2236,10 @@ static int win_chr_poll(void *opaque)
     return 0;
 }
 
-static CharDriverState *qemu_chr_open_win(const char *filename)
-{
-    CharDriverState *chr;
+static CharDriverState *qemu_chr_open_win(CharDriverState *chr, const char 
*filename)
+{
     WinCharState *s;
     
-    chr = qemu_mallocz(sizeof(CharDriverState));
-    if (!chr)
-        return NULL;
     s = qemu_mallocz(sizeof(WinCharState));
     if (!s) {
         free(chr);
@@ -2354,14 +2337,10 @@ static int win_chr_pipe_init(CharDriverS
 }
 
 
-static CharDriverState *qemu_chr_open_win_pipe(const char *filename)
-{
-    CharDriverState *chr;
+static CharDriverState *qemu_chr_open_win_pipe(CharDriverState *chr, const 
char *filename)
+{
     WinCharState *s;
 
-    chr = qemu_mallocz(sizeof(CharDriverState));
-    if (!chr)
-        return NULL;
     s = qemu_mallocz(sizeof(WinCharState));
     if (!s) {
         free(chr);
@@ -2380,14 +2359,10 @@ static CharDriverState *qemu_chr_open_wi
     return chr;
 }
 
-static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
-{
-    CharDriverState *chr;
+static CharDriverState *qemu_chr_open_win_file(CharDriverState *chr, HANDLE 
fd_out)
+{
     WinCharState *s;
 
-    chr = qemu_mallocz(sizeof(CharDriverState));
-    if (!chr)
-        return NULL;
     s = qemu_mallocz(sizeof(WinCharState));
     if (!s) {
         free(chr);
@@ -2400,7 +2375,7 @@ static CharDriverState *qemu_chr_open_wi
     return chr;
 }
     
-static CharDriverState *qemu_chr_open_win_file_out(const char *file_out)
+static CharDriverState *qemu_chr_open_win_file_out(CharDriverState *chr, const 
char *file_out)
 {
     HANDLE fd_out;
     
@@ -2409,7 +2384,7 @@ static CharDriverState *qemu_chr_open_wi
     if (fd_out == INVALID_HANDLE_VALUE)
         return NULL;
 
-    return qemu_chr_open_win_file(fd_out);
+    return qemu_chr_open_win_file(chr, fd_out);
 }
 #endif
 
@@ -2489,16 +2464,12 @@ int parse_host_src_port(struct sockaddr_
                         struct sockaddr_in *saddr,
                         const char *str);
 
-static CharDriverState *qemu_chr_open_udp(const char *def)
-{
-    CharDriverState *chr = NULL;
+static CharDriverState *qemu_chr_open_udp(CharDriverState *chr, const char 
*def)
+{
     NetCharDriver *s = NULL;
     int fd = -1;
     struct sockaddr_in saddr;
 
-    chr = qemu_mallocz(sizeof(CharDriverState));
-    if (!chr)
-        goto return_err;
     s = qemu_mallocz(sizeof(NetCharDriver));
     if (!s)
         goto return_err;
@@ -2735,11 +2706,11 @@ static void tcp_chr_close(CharDriverStat
     qemu_free(s);
 }
 
-static CharDriverState *qemu_chr_open_tcp(const char *host_str, 
+static CharDriverState *qemu_chr_open_tcp(CharDriverState *chr,
+                                         const char *host_str, 
                                           int is_telnet,
                                          int is_unix)
 {
-    CharDriverState *chr = NULL;
     TCPCharDriver *s = NULL;
     int fd = -1, ret, err, val;
     int is_listen = 0;
@@ -2785,9 +2756,6 @@ static CharDriverState *qemu_chr_open_tc
     if (!is_listen)
         is_waitconnect = 0;
 
-    chr = qemu_mallocz(sizeof(CharDriverState));
-    if (!chr)
-        goto fail;
     s = qemu_mallocz(sizeof(TCPCharDriver));
     if (!s)
         goto fail;
@@ -2881,31 +2849,36 @@ static CharDriverState *qemu_chr_open_tc
     return NULL;
 }
 
-CharDriverState *qemu_chr_open(const char *filename)
+CharDriverState *qemu_chr_open2(CharDriverState *chr, const char *filename)
 {
     const char *p;
-    CharDriverState *chr;
+    CharDriverState *saved_chr;
+
+    saved_chr = chr;
+
+    if (chr->filename)
+       free(chr->filename);
+    chr->filename = strdup(filename);
 
     if (!strcmp(filename, "vc")) {
-        chr = text_console_init(&display_state);
+        chr = text_console_init(chr, &display_state);
     } else if (!strcmp(filename, "null")) {
-        chr = qemu_chr_open_null();
+        chr = qemu_chr_open_null(chr);
     } else 
     if (strstart(filename, "tcp:", &p)) {
-        chr = qemu_chr_open_tcp(p, 0, 0);
+        chr = qemu_chr_open_tcp(chr, p, 0, 0);
     } else
     if (strstart(filename, "telnet:", &p)) {
-        chr = qemu_chr_open_tcp(p, 1, 0);
+        chr = qemu_chr_open_tcp(chr, p, 1, 0);
     } else
     if (strstart(filename, "udp:", &p)) {
-        chr = qemu_chr_open_udp(p);
+        chr = qemu_chr_open_udp(chr, p);
     } else
     if (strstart(filename, "mon:", &p)) {
-        CharDriverState *drv = qemu_chr_open(p);
-        if (drv) {
-            drv = qemu_chr_open_mux(drv);
-            monitor_init(drv, !nographic);
-            chr = drv;
+        chr = qemu_chr_open(p);
+        if (chr) {
+            chr = qemu_chr_open_mux(chr);
+            monitor_init(chr, !nographic);
         } else {
            printf("Unable to open driver: %s\n", p);
            return 0;
@@ -2913,44 +2886,61 @@ CharDriverState *qemu_chr_open(const cha
     } else
 #ifndef _WIN32
     if (strstart(filename, "unix:", &p)) {
-       chr = qemu_chr_open_tcp(p, 0, 1);
+       chr = qemu_chr_open_tcp(chr, p, 0, 1);
     } else if (strstart(filename, "file:", &p)) {
-        chr = qemu_chr_open_file_out(p);
+        chr = qemu_chr_open_file_out(chr, p);
     } else if (strstart(filename, "pipe:", &p)) {
-        chr = qemu_chr_open_pipe(p);
+        chr = qemu_chr_open_pipe(chr, p);
     } else if (!strcmp(filename, "pty")) {
-        chr = qemu_chr_open_pty();
+        chr = qemu_chr_open_pty(chr);
     } else if (!strcmp(filename, "stdio")) {
-        chr = qemu_chr_open_stdio();
+        chr = qemu_chr_open_stdio(chr);
     } else 
 #endif
 #if defined(__linux__)
     if (strstart(filename, "/dev/parport", NULL)) {
-        chr = qemu_chr_open_pp(filename);
+        chr = qemu_chr_open_pp(chr, filename);
     } else 
     if (strstart(filename, "/dev/", NULL)) {
-        chr = qemu_chr_open_tty(filename);
+        chr = qemu_chr_open_tty(chr, filename);
     } else 
 #endif
 #ifdef _WIN32
     if (strstart(filename, "COM", NULL)) {
-        chr = qemu_chr_open_win(filename);
+        chr = qemu_chr_open_win(chr, filename);
     } else
     if (strstart(filename, "pipe:", &p)) {
-        chr = qemu_chr_open_win_pipe(p);
+        chr = qemu_chr_open_win_pipe(chr, p);
     } else
     if (strstart(filename, "file:", &p)) {
-        chr = qemu_chr_open_win_file_out(p);
+        chr = qemu_chr_open_win_file_out(chr, p);
     } else
 #endif
     {
-        return NULL;
-    }
-
-    if (chr)
-       chr->filename = strdup(filename);
+        chr = NULL;
+    }
+
+    if (chr == NULL) {
+       free(saved_chr->filename);
+       saved_chr->filename = NULL;
+    }
 
     return chr;
+}
+
+CharDriverState *qemu_chr_open(const char *filename)
+{
+    CharDriverState *chr, *drv;
+
+    chr = qemu_mallocz(sizeof(CharDriverState));
+    if (!chr)
+       return NULL;
+
+    drv = qemu_chr_open2(chr, filename);
+    if (!drv)
+       qemu_free(chr);
+       
+    return drv;
 }
 
 void qemu_chr_close(CharDriverState *chr)
@@ -7562,7 +7552,7 @@ int main(int argc, char **argv)
 
     for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
         const char *devname = parallel_devices[i];
-        if (devname[0] != '\0' && strcmp(devname, "none")) {
+       if (devname[0] != '\0' && strcmp(devname, "none")) {
             parallel_hds[i] = qemu_chr_open(devname);
             if (!parallel_hds[i]) {
                 fprintf(stderr, "qemu: could not open parallel device '%s'\n", 
@@ -7571,7 +7561,7 @@ int main(int argc, char **argv)
             }
             if (!strcmp(devname, "vc"))
                 qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
-        }
+       }
     }
 
     machine->init(ram_size, vga_ram_size, boot_device,
diff -r 6b23d9afec55 vl.h
--- a/vl.h      Sat Mar 03 21:35:55 2007 -0600
+++ b/vl.h      Sat Mar 03 21:55:54 2007 -0600
@@ -311,6 +311,7 @@ typedef struct CharDriverState {
 } CharDriverState;
 
 CharDriverState *qemu_chr_open(const char *filename);
+CharDriverState *qemu_chr_open2(CharDriverState *chr, const char *filename);
 void qemu_chr_printf(CharDriverState *s, const char *fmt, ...);
 int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len);
 void qemu_chr_send_event(CharDriverState *s, int event);
@@ -342,7 +343,7 @@ void vga_hw_screen_dump(const char *file
 void vga_hw_screen_dump(const char *filename);
 
 int is_graphic_console(void);
-CharDriverState *text_console_init(DisplayState *ds);
+CharDriverState *text_console_init(CharDriverState *chr, DisplayState *ds);
 void console_select(unsigned int index);
 
 /* serial ports */
@@ -921,6 +922,7 @@ void cocoa_display_init(DisplayState *ds
 
 /* vnc.c */
 void vnc_display_init(DisplayState *ds, const char *display);
+int vnc_display_open(DisplayState *ds, const char *display);
 void do_info_vnc(void);
 
 /* x_keymap.c */
diff -r 6b23d9afec55 vnc.c
--- a/vnc.c     Sat Mar 03 21:35:55 2007 -0600
+++ b/vnc.c     Sat Mar 03 21:55:54 2007 -0600
@@ -73,7 +73,7 @@ struct VncState
     int last_x;
     int last_y;
 
-    const char *display;
+    char *display;
 
     Buffer output;
     Buffer input;
@@ -1160,7 +1160,7 @@ static void vnc_listen_read(void *opaque
 
 extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
 
-void vnc_display_init(DisplayState *ds, const char *arg)
+int vnc_display_open(DisplayState *ds, const char *arg)
 {
     struct sockaddr *addr;
     struct sockaddr_in iaddr;
@@ -1172,38 +1172,31 @@ void vnc_display_init(DisplayState *ds, 
     const char *p;
     VncState *vs;
 
-    vs = qemu_mallocz(sizeof(VncState));
-    if (!vs)
-       exit(1);
-
-    ds->opaque = vs;
-    vnc_state = vs;
-    vs->display = arg;
-
-    vs->lsock = -1;
-    vs->csock = -1;
-    vs->depth = 4;
-    vs->last_x = -1;
-    vs->last_y = -1;
-
-    vs->ds = ds;
-
-    if (!keyboard_layout)
-       keyboard_layout = "en-us";
-
-    vs->kbd_layout = init_keyboard_layout(keyboard_layout);
-    if (!vs->kbd_layout)
-       exit(1);
-
-    vs->ds->data = NULL;
-    vs->ds->dpy_update = vnc_dpy_update;
-    vs->ds->dpy_resize = vnc_dpy_resize;
-    vs->ds->dpy_refresh = vnc_dpy_refresh;
-
-    memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
-
-    vnc_dpy_resize(vs->ds, 640, 400);
-
+    if (ds == NULL)
+       ds = vnc_state->ds;
+
+    vs = ds->opaque;
+
+    free(vs->display);
+    vs->display = strdup(arg);
+    if (vs->csock != -1) {
+       qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
+       closesocket(vs->csock);
+       vs->csock = -1;
+       buffer_reset(&vs->input);
+       buffer_reset(&vs->output);
+       vs->need_update = 0;
+    }
+
+    if (vs->lsock != -1) {
+       qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
+       close(vs->lsock);
+       vs->lsock = -1;
+    }  
+
+    if (strcmp(arg, "null") == 0)
+       return 0;
+    else
 #ifndef _WIN32
     if (strstart(arg, "unix:", &p)) {
        addr = (struct sockaddr *)&uaddr;
@@ -1212,7 +1205,7 @@ void vnc_display_init(DisplayState *ds, 
        vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
        if (vs->lsock == -1) {
            fprintf(stderr, "Could not create socket\n");
-           exit(1);
+           return -1;
        }
 
        uaddr.sun_family = AF_UNIX;
@@ -1229,12 +1222,12 @@ void vnc_display_init(DisplayState *ds, 
        vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
        if (vs->lsock == -1) {
            fprintf(stderr, "Could not create socket\n");
-           exit(1);
+           return -1;
        }
 
        if (parse_host_port(&iaddr, arg) < 0) {
            fprintf(stderr, "Could not parse VNC address\n");
-           exit(1);
+           return -1;
        }
            
        iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900);
@@ -1244,22 +1237,63 @@ void vnc_display_init(DisplayState *ds, 
                         (const char *)&reuse_addr, sizeof(reuse_addr));
        if (ret == -1) {
            fprintf(stderr, "setsockopt() failed\n");
-           exit(1);
+           return -1;
        }
     }
 
     if (bind(vs->lsock, addr, addrlen) == -1) {
        fprintf(stderr, "bind() failed\n");
-       exit(1);
+       return -1;
     }
 
     if (listen(vs->lsock, 1) == -1) {
        fprintf(stderr, "listen() failed\n");
+       return -1;
+    }
+
+    ret = qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, 
NULL, vs);
+    if (ret == -1)
+       return -1;
+
+    return 0;
+}
+
+void vnc_display_init(DisplayState *ds, const char *arg)
+{
+    VncState *vs;
+
+    vs = qemu_mallocz(sizeof(VncState));
+    if (!vs)
        exit(1);
-    }
-
-    ret = qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, 
NULL, vs);
-    if (ret == -1) {
+
+    ds->opaque = vs;
+    vnc_state = vs;
+
+    vs->lsock = -1;
+    vs->csock = -1;
+    vs->depth = 4;
+    vs->last_x = -1;
+    vs->last_y = -1;
+
+    vs->ds = ds;
+    vs->display = NULL;
+
+    if (!keyboard_layout)
+       keyboard_layout = "en-us";
+
+    vs->kbd_layout = init_keyboard_layout(keyboard_layout);
+    if (!vs->kbd_layout)
        exit(1);
-    }
-}
+
+    vs->ds->data = NULL;
+    vs->ds->dpy_update = vnc_dpy_update;
+    vs->ds->dpy_resize = vnc_dpy_resize;
+    vs->ds->dpy_refresh = vnc_dpy_refresh;
+
+    memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
+
+    vnc_dpy_resize(vs->ds, 640, 400);
+
+    if (vnc_display_open(vs->ds, arg) == -1)
+       exit(1);
+}
diff -r 6b23d9afec55 qemu-doc.texi
--- a/qemu-doc.texi     Sat Mar 03 21:35:55 2007 -0600
+++ b/qemu-doc.texi     Sat Mar 03 22:09:34 2007 -0600
@@ -267,7 +267,8 @@ will only be allowed from @var{interface
 will only be allowed from @var{interface} on display @var{d}. Optionally,
 @var{interface} can be omitted.  @var{display} can also be in the form
 @var{unix:path} where @var{path} is the location of a unix socket to listen for
-connections on.
+connections on.  @var{display} can also be @var{null} which create a VNC server
+that does not listen on any interfaces.
 
 
 @item -k language

reply via email to

[Prev in Thread] Current Thread [Next in Thread]