Commit 73fc97427b6410b9ebd38b8d88831be050ce189b

Authored by ths
1 parent ffd843bc

Unix domain socket support for VNC, by Anthony Liguori.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2260 c046a42c-6fe2-441c-8c8c-71466251a162
qemu-doc.texi
@@ -247,14 +247,21 @@ command line application. The emulated serial port is redirected on @@ -247,14 +247,21 @@ command line application. The emulated serial port is redirected on
247 the console. Therefore, you can still use QEMU to debug a Linux kernel 247 the console. Therefore, you can still use QEMU to debug a Linux kernel
248 with a serial console. 248 with a serial console.
249 249
250 -@item -vnc d 250 +@item -vnc display
251 251
252 Normally, QEMU uses SDL to display the VGA output. With this option, 252 Normally, QEMU uses SDL to display the VGA output. With this option,
253 -you can have QEMU listen on VNC display @var{d} and redirect the VGA 253 +you can have QEMU listen on VNC display @var{display} and redirect the VGA
254 display over the VNC session. It is very useful to enable the usb 254 display over the VNC session. It is very useful to enable the usb
255 tablet device when using this option (option @option{-usbdevice 255 tablet device when using this option (option @option{-usbdevice
256 tablet}). When using the VNC display, you must use the @option{-k} 256 tablet}). When using the VNC display, you must use the @option{-k}
257 -option to set the keyboard layout. 257 +option to set the keyboard layout if you are not using en-us.
  258 +
  259 +@var{display} may be in the form @var{interface:d}, in which case connections
  260 +will only be allowed from @var{interface} on display @var{d}. Optionally,
  261 +@var{interface} can be omitted. @var{display} can also be in the form
  262 +@var{unix:path} where @var{path} is the location of a unix socket to listen for
  263 +connections on.
  264 +
258 265
259 @item -k language 266 @item -k language
260 267
@@ -152,7 +152,7 @@ int win2k_install_hack = 0; @@ -152,7 +152,7 @@ int win2k_install_hack = 0;
152 int usb_enabled = 0; 152 int usb_enabled = 0;
153 static VLANState *first_vlan; 153 static VLANState *first_vlan;
154 int smp_cpus = 1; 154 int smp_cpus = 1;
155 -int vnc_display = -1; 155 +const char *vnc_display;
156 #if defined(TARGET_SPARC) 156 #if defined(TARGET_SPARC)
157 #define MAX_CPUS 16 157 #define MAX_CPUS 16
158 #elif defined(TARGET_I386) 158 #elif defined(TARGET_I386)
@@ -6818,11 +6818,7 @@ int main(int argc, char **argv) @@ -6818,11 +6818,7 @@ int main(int argc, char **argv)
6818 } 6818 }
6819 break; 6819 break;
6820 case QEMU_OPTION_vnc: 6820 case QEMU_OPTION_vnc:
6821 - vnc_display = atoi(optarg);  
6822 - if (vnc_display < 0) {  
6823 - fprintf(stderr, "Invalid VNC display\n");  
6824 - exit(1);  
6825 - } 6821 + vnc_display = optarg;
6826 break; 6822 break;
6827 case QEMU_OPTION_no_acpi: 6823 case QEMU_OPTION_no_acpi:
6828 acpi_enabled = 0; 6824 acpi_enabled = 0;
@@ -6946,7 +6942,7 @@ int main(int argc, char **argv) @@ -6946,7 +6942,7 @@ int main(int argc, char **argv)
6946 /* terminal init */ 6942 /* terminal init */
6947 if (nographic) { 6943 if (nographic) {
6948 dumb_display_init(ds); 6944 dumb_display_init(ds);
6949 - } else if (vnc_display != -1) { 6945 + } else if (vnc_display != NULL) {
6950 vnc_display_init(ds, vnc_display); 6946 vnc_display_init(ds, vnc_display);
6951 } else { 6947 } else {
6952 #if defined(CONFIG_SDL) 6948 #if defined(CONFIG_SDL)
@@ -867,7 +867,7 @@ void sdl_display_init(DisplayState *ds, int full_screen); @@ -867,7 +867,7 @@ void sdl_display_init(DisplayState *ds, int full_screen);
867 void cocoa_display_init(DisplayState *ds, int full_screen); 867 void cocoa_display_init(DisplayState *ds, int full_screen);
868 868
869 /* vnc.c */ 869 /* vnc.c */
870 -void vnc_display_init(DisplayState *ds, int display); 870 +void vnc_display_init(DisplayState *ds, const char *display);
871 871
872 /* ide.c */ 872 /* ide.c */
873 #define MAX_DISKS 4 873 #define MAX_DISKS 4
@@ -1101,10 +1101,18 @@ static void vnc_listen_read(void *opaque) @@ -1101,10 +1101,18 @@ static void vnc_listen_read(void *opaque)
1101 } 1101 }
1102 } 1102 }
1103 1103
1104 -void vnc_display_init(DisplayState *ds, int display) 1104 +extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
  1105 +
  1106 +void vnc_display_init(DisplayState *ds, const char *arg)
1105 { 1107 {
1106 - struct sockaddr_in addr; 1108 + struct sockaddr *addr;
  1109 + struct sockaddr_in iaddr;
  1110 +#ifndef _WIN32
  1111 + struct sockaddr_un uaddr;
  1112 +#endif
1107 int reuse_addr, ret; 1113 int reuse_addr, ret;
  1114 + socklen_t addrlen;
  1115 + const char *p;
1108 VncState *vs; 1116 VncState *vs;
1109 1117
1110 vs = qemu_mallocz(sizeof(VncState)); 1118 vs = qemu_mallocz(sizeof(VncState));
@@ -1126,25 +1134,60 @@ void vnc_display_init(DisplayState *ds, int display) @@ -1126,25 +1134,60 @@ void vnc_display_init(DisplayState *ds, int display)
1126 if (!vs->kbd_layout) 1134 if (!vs->kbd_layout)
1127 exit(1); 1135 exit(1);
1128 1136
1129 - vs->lsock = socket(PF_INET, SOCK_STREAM, 0);  
1130 - if (vs->lsock == -1) {  
1131 - fprintf(stderr, "Could not create socket\n");  
1132 - exit(1);  
1133 - } 1137 + vs->ds->data = NULL;
  1138 + vs->ds->dpy_update = vnc_dpy_update;
  1139 + vs->ds->dpy_resize = vnc_dpy_resize;
  1140 + vs->ds->dpy_refresh = vnc_dpy_refresh;
  1141 +
  1142 + memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1134 1143
1135 - addr.sin_family = AF_INET;  
1136 - addr.sin_port = htons(5900 + display);  
1137 - memset(&addr.sin_addr, 0, sizeof(addr.sin_addr)); 1144 + vnc_dpy_resize(vs->ds, 640, 400);
1138 1145
1139 - reuse_addr = 1;  
1140 - ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,  
1141 - (const char *)&reuse_addr, sizeof(reuse_addr));  
1142 - if (ret == -1) {  
1143 - fprintf(stderr, "setsockopt() failed\n");  
1144 - exit(1); 1146 +#ifndef _WIN32
  1147 + if (strstart(arg, "unix:", &p)) {
  1148 + addr = (struct sockaddr *)&uaddr;
  1149 + addrlen = sizeof(uaddr);
  1150 +
  1151 + vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
  1152 + if (vs->lsock == -1) {
  1153 + fprintf(stderr, "Could not create socket\n");
  1154 + exit(1);
  1155 + }
  1156 +
  1157 + uaddr.sun_family = AF_UNIX;
  1158 + memset(uaddr.sun_path, 0, 108);
  1159 + snprintf(uaddr.sun_path, 108, "%s", p);
  1160 +
  1161 + unlink(uaddr.sun_path);
  1162 + } else
  1163 +#endif
  1164 + {
  1165 + addr = (struct sockaddr *)&iaddr;
  1166 + addrlen = sizeof(iaddr);
  1167 +
  1168 + vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
  1169 + if (vs->lsock == -1) {
  1170 + fprintf(stderr, "Could not create socket\n");
  1171 + exit(1);
  1172 + }
  1173 +
  1174 + if (parse_host_port(&iaddr, arg) < 0) {
  1175 + fprintf(stderr, "Could not parse VNC address\n");
  1176 + exit(1);
  1177 + }
  1178 +
  1179 + iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900);
  1180 +
  1181 + reuse_addr = 1;
  1182 + ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
  1183 + (const char *)&reuse_addr, sizeof(reuse_addr));
  1184 + if (ret == -1) {
  1185 + fprintf(stderr, "setsockopt() failed\n");
  1186 + exit(1);
  1187 + }
1145 } 1188 }
1146 1189
1147 - if (bind(vs->lsock, (struct sockaddr *)&addr, sizeof(addr)) == -1) { 1190 + if (bind(vs->lsock, addr, addrlen) == -1) {
1148 fprintf(stderr, "bind() failed\n"); 1191 fprintf(stderr, "bind() failed\n");
1149 exit(1); 1192 exit(1);
1150 } 1193 }
@@ -1158,13 +1201,4 @@ void vnc_display_init(DisplayState *ds, int display) @@ -1158,13 +1201,4 @@ void vnc_display_init(DisplayState *ds, int display)
1158 if (ret == -1) { 1201 if (ret == -1) {
1159 exit(1); 1202 exit(1);
1160 } 1203 }
1161 -  
1162 - vs->ds->data = NULL;  
1163 - vs->ds->dpy_update = vnc_dpy_update;  
1164 - vs->ds->dpy_resize = vnc_dpy_resize;  
1165 - vs->ds->dpy_refresh = vnc_dpy_refresh;  
1166 -  
1167 - memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));  
1168 -  
1169 - vnc_dpy_resize(vs->ds, 640, 400);  
1170 } 1204 }