Commit 71cab5ca0d9f10cf9f07eaf3033687bf85459d52
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
vl.c
| @@ -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); |
vl.h
| @@ -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 */ |
vnc.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 | } |