Commit 71cab5ca0d9f10cf9f07eaf3033687bf85459d52

Authored by ths
1 parent 6ab43fdc

Refactor VNC server setup API, by Daniel P. Berrange.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3133 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 3 changed files with 82 additions and 29 deletions
@@ -8319,7 +8319,9 @@ int main(int argc, char **argv) @@ -8319,7 +8319,9 @@ int main(int argc, char **argv)
8319 /* nearly nothing to do */ 8319 /* nearly nothing to do */
8320 dumb_display_init(ds); 8320 dumb_display_init(ds);
8321 } else if (vnc_display != NULL) { 8321 } else if (vnc_display != NULL) {
8322 - vnc_display_init(ds, vnc_display); 8322 + vnc_display_init(ds);
  8323 + if (vnc_display_open(ds, vnc_display) < 0)
  8324 + exit(1);
8323 } else { 8325 } else {
8324 #if defined(CONFIG_SDL) 8326 #if defined(CONFIG_SDL)
8325 sdl_display_init(ds, full_screen, no_frame); 8327 sdl_display_init(ds, full_screen, no_frame);
@@ -967,7 +967,9 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame); @@ -967,7 +967,9 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame);
967 void cocoa_display_init(DisplayState *ds, int full_screen); 967 void cocoa_display_init(DisplayState *ds, int full_screen);
968 968
969 /* vnc.c */ 969 /* vnc.c */
970 -void vnc_display_init(DisplayState *ds, const char *display); 970 +void vnc_display_init(DisplayState *ds);
  971 +void vnc_display_close(DisplayState *ds);
  972 +int vnc_display_open(DisplayState *ds, const char *display);
971 void do_info_vnc(void); 973 void do_info_vnc(void);
972 974
973 /* x_keymap.c */ 975 /* x_keymap.c */
@@ -73,7 +73,7 @@ struct VncState @@ -73,7 +73,7 @@ struct VncState
73 int last_x; 73 int last_x;
74 int last_y; 74 int last_y;
75 75
76 - const char *display; 76 + char *display;
77 77
78 Buffer output; 78 Buffer output;
79 Buffer input; 79 Buffer input;
@@ -1169,16 +1169,8 @@ static void vnc_listen_read(void *opaque) @@ -1169,16 +1169,8 @@ static void vnc_listen_read(void *opaque)
1169 1169
1170 extern int parse_host_port(struct sockaddr_in *saddr, const char *str); 1170 extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
1171 1171
1172 -void vnc_display_init(DisplayState *ds, const char *arg) 1172 +void vnc_display_init(DisplayState *ds)
1173 { 1173 {
1174 - struct sockaddr *addr;  
1175 - struct sockaddr_in iaddr;  
1176 -#ifndef _WIN32  
1177 - struct sockaddr_un uaddr;  
1178 -#endif  
1179 - int reuse_addr, ret;  
1180 - socklen_t addrlen;  
1181 - const char *p;  
1182 VncState *vs; 1174 VncState *vs;
1183 1175
1184 vs = qemu_mallocz(sizeof(VncState)); 1176 vs = qemu_mallocz(sizeof(VncState));
@@ -1187,7 +1179,7 @@ void vnc_display_init(DisplayState *ds, const char *arg) @@ -1187,7 +1179,7 @@ void vnc_display_init(DisplayState *ds, const char *arg)
1187 1179
1188 ds->opaque = vs; 1180 ds->opaque = vs;
1189 vnc_state = vs; 1181 vnc_state = vs;
1190 - vs->display = arg; 1182 + vs->display = NULL;
1191 1183
1192 vs->lsock = -1; 1184 vs->lsock = -1;
1193 vs->csock = -1; 1185 vs->csock = -1;
@@ -1212,7 +1204,49 @@ void vnc_display_init(DisplayState *ds, const char *arg) @@ -1212,7 +1204,49 @@ void vnc_display_init(DisplayState *ds, const char *arg)
1212 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row)); 1204 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1213 1205
1214 vnc_dpy_resize(vs->ds, 640, 400); 1206 vnc_dpy_resize(vs->ds, 640, 400);
  1207 +}
  1208 +
  1209 +void vnc_display_close(DisplayState *ds)
  1210 +{
  1211 + VncState *vs = (VncState *)ds->opaque;
  1212 +
  1213 + if (vs->display) {
  1214 + qemu_free(vs->display);
  1215 + vs->display = NULL;
  1216 + }
  1217 + if (vs->lsock != -1) {
  1218 + qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
  1219 + close(vs->lsock);
  1220 + vs->lsock = -1;
  1221 + }
  1222 + if (vs->csock != -1) {
  1223 + qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
  1224 + closesocket(vs->csock);
  1225 + vs->csock = -1;
  1226 + buffer_reset(&vs->input);
  1227 + buffer_reset(&vs->output);
  1228 + vs->need_update = 0;
  1229 + }
  1230 +}
  1231 +
  1232 +int vnc_display_open(DisplayState *ds, const char *arg)
  1233 +{
  1234 + struct sockaddr *addr;
  1235 + struct sockaddr_in iaddr;
  1236 +#ifndef _WIN32
  1237 + struct sockaddr_un uaddr;
  1238 +#endif
  1239 + int reuse_addr, ret;
  1240 + socklen_t addrlen;
  1241 + const char *p;
  1242 + VncState *vs = (VncState *)ds->opaque;
  1243 +
  1244 + vnc_display_close(ds);
  1245 + if (strcmp(arg, "none") == 0)
  1246 + return 0;
1215 1247
  1248 + if (!(vs->display = strdup(arg)))
  1249 + return -1;
1216 #ifndef _WIN32 1250 #ifndef _WIN32
1217 if (strstart(arg, "unix:", &p)) { 1251 if (strstart(arg, "unix:", &p)) {
1218 addr = (struct sockaddr *)&uaddr; 1252 addr = (struct sockaddr *)&uaddr;
@@ -1221,7 +1255,9 @@ void vnc_display_init(DisplayState *ds, const char *arg) @@ -1221,7 +1255,9 @@ void vnc_display_init(DisplayState *ds, const char *arg)
1221 vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0); 1255 vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
1222 if (vs->lsock == -1) { 1256 if (vs->lsock == -1) {
1223 fprintf(stderr, "Could not create socket\n"); 1257 fprintf(stderr, "Could not create socket\n");
1224 - exit(1); 1258 + free(vs->display);
  1259 + vs->display = NULL;
  1260 + return -1;
1225 } 1261 }
1226 1262
1227 uaddr.sun_family = AF_UNIX; 1263 uaddr.sun_family = AF_UNIX;
@@ -1235,40 +1271,53 @@ void vnc_display_init(DisplayState *ds, const char *arg) @@ -1235,40 +1271,53 @@ void vnc_display_init(DisplayState *ds, const char *arg)
1235 addr = (struct sockaddr *)&iaddr; 1271 addr = (struct sockaddr *)&iaddr;
1236 addrlen = sizeof(iaddr); 1272 addrlen = sizeof(iaddr);
1237 1273
1238 - vs->lsock = socket(PF_INET, SOCK_STREAM, 0);  
1239 - if (vs->lsock == -1) {  
1240 - fprintf(stderr, "Could not create socket\n");  
1241 - exit(1);  
1242 - }  
1243 -  
1244 if (parse_host_port(&iaddr, arg) < 0) { 1274 if (parse_host_port(&iaddr, arg) < 0) {
1245 fprintf(stderr, "Could not parse VNC address\n"); 1275 fprintf(stderr, "Could not parse VNC address\n");
1246 - exit(1); 1276 + free(vs->display);
  1277 + vs->display = NULL;
  1278 + return -1;
1247 } 1279 }
1248 - 1280 +
1249 iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900); 1281 iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900);
1250 1282
  1283 + vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
  1284 + if (vs->lsock == -1) {
  1285 + fprintf(stderr, "Could not create socket\n");
  1286 + free(vs->display);
  1287 + vs->display = NULL;
  1288 + return -1;
  1289 + }
  1290 +
1251 reuse_addr = 1; 1291 reuse_addr = 1;
1252 ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR, 1292 ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
1253 (const char *)&reuse_addr, sizeof(reuse_addr)); 1293 (const char *)&reuse_addr, sizeof(reuse_addr));
1254 if (ret == -1) { 1294 if (ret == -1) {
1255 fprintf(stderr, "setsockopt() failed\n"); 1295 fprintf(stderr, "setsockopt() failed\n");
1256 - exit(1); 1296 + close(vs->lsock);
  1297 + vs->lsock = -1;
  1298 + free(vs->display);
  1299 + vs->display = NULL;
  1300 + return -1;
1257 } 1301 }
1258 } 1302 }
1259 1303
1260 if (bind(vs->lsock, addr, addrlen) == -1) { 1304 if (bind(vs->lsock, addr, addrlen) == -1) {
1261 fprintf(stderr, "bind() failed\n"); 1305 fprintf(stderr, "bind() failed\n");
1262 - exit(1); 1306 + close(vs->lsock);
  1307 + vs->lsock = -1;
  1308 + free(vs->display);
  1309 + vs->display = NULL;
  1310 + return -1;
1263 } 1311 }
1264 1312
1265 if (listen(vs->lsock, 1) == -1) { 1313 if (listen(vs->lsock, 1) == -1) {
1266 fprintf(stderr, "listen() failed\n"); 1314 fprintf(stderr, "listen() failed\n");
1267 - exit(1); 1315 + close(vs->lsock);
  1316 + vs->lsock = -1;
  1317 + free(vs->display);
  1318 + vs->display = NULL;
  1319 + return -1;
1268 } 1320 }
1269 1321
1270 - ret = qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);  
1271 - if (ret == -1) {  
1272 - exit(1);  
1273 - } 1322 + return qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);
1274 } 1323 }