Commit 71cab5ca authored by ths's avatar ths
Browse files

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
parent 6ab43fdc
...@@ -8319,7 +8319,9 @@ int main(int argc, char **argv) ...@@ -8319,7 +8319,9 @@ int main(int argc, char **argv)
/* nearly nothing to do */ /* nearly nothing to do */
dumb_display_init(ds); dumb_display_init(ds);
} else if (vnc_display != NULL) { } else if (vnc_display != NULL) {
vnc_display_init(ds, vnc_display); vnc_display_init(ds);
if (vnc_display_open(ds, vnc_display) < 0)
exit(1);
} else { } else {
#if defined(CONFIG_SDL) #if defined(CONFIG_SDL)
sdl_display_init(ds, full_screen, no_frame); 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);
void cocoa_display_init(DisplayState *ds, int full_screen); void cocoa_display_init(DisplayState *ds, int full_screen);
/* vnc.c */ /* vnc.c */
void vnc_display_init(DisplayState *ds, const char *display); void vnc_display_init(DisplayState *ds);
void vnc_display_close(DisplayState *ds);
int vnc_display_open(DisplayState *ds, const char *display);
void do_info_vnc(void); void do_info_vnc(void);
/* x_keymap.c */ /* x_keymap.c */
......
...@@ -73,7 +73,7 @@ struct VncState ...@@ -73,7 +73,7 @@ struct VncState
int last_x; int last_x;
int last_y; int last_y;
const char *display; char *display;
Buffer output; Buffer output;
Buffer input; Buffer input;
...@@ -1169,16 +1169,8 @@ static void vnc_listen_read(void *opaque) ...@@ -1169,16 +1169,8 @@ static void vnc_listen_read(void *opaque)
extern int parse_host_port(struct sockaddr_in *saddr, const char *str); extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
void vnc_display_init(DisplayState *ds, const char *arg) void vnc_display_init(DisplayState *ds)
{ {
struct sockaddr *addr;
struct sockaddr_in iaddr;
#ifndef _WIN32
struct sockaddr_un uaddr;
#endif
int reuse_addr, ret;
socklen_t addrlen;
const char *p;
VncState *vs; VncState *vs;
vs = qemu_mallocz(sizeof(VncState)); 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)
ds->opaque = vs; ds->opaque = vs;
vnc_state = vs; vnc_state = vs;
vs->display = arg; vs->display = NULL;
vs->lsock = -1; vs->lsock = -1;
vs->csock = -1; 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)
memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row)); memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
vnc_dpy_resize(vs->ds, 640, 400); vnc_dpy_resize(vs->ds, 640, 400);
}
void vnc_display_close(DisplayState *ds)
{
VncState *vs = (VncState *)ds->opaque;
if (vs->display) {
qemu_free(vs->display);
vs->display = NULL;
}
if (vs->lsock != -1) {
qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
close(vs->lsock);
vs->lsock = -1;
}
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;
}
}
int vnc_display_open(DisplayState *ds, const char *arg)
{
struct sockaddr *addr;
struct sockaddr_in iaddr;
#ifndef _WIN32
struct sockaddr_un uaddr;
#endif
int reuse_addr, ret;
socklen_t addrlen;
const char *p;
VncState *vs = (VncState *)ds->opaque;
vnc_display_close(ds);
if (strcmp(arg, "none") == 0)
return 0;
if (!(vs->display = strdup(arg)))
return -1;
#ifndef _WIN32 #ifndef _WIN32
if (strstart(arg, "unix:", &p)) { if (strstart(arg, "unix:", &p)) {
addr = (struct sockaddr *)&uaddr; 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)
vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0); vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
if (vs->lsock == -1) { if (vs->lsock == -1) {
fprintf(stderr, "Could not create socket\n"); fprintf(stderr, "Could not create socket\n");
exit(1); free(vs->display);
vs->display = NULL;
return -1;
} }
uaddr.sun_family = AF_UNIX; 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)
addr = (struct sockaddr *)&iaddr; addr = (struct sockaddr *)&iaddr;
addrlen = sizeof(iaddr); addrlen = sizeof(iaddr);
vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
if (vs->lsock == -1) {
fprintf(stderr, "Could not create socket\n");
exit(1);
}
if (parse_host_port(&iaddr, arg) < 0) { if (parse_host_port(&iaddr, arg) < 0) {
fprintf(stderr, "Could not parse VNC address\n"); fprintf(stderr, "Could not parse VNC address\n");
exit(1); free(vs->display);
vs->display = NULL;
return -1;
} }
iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900); iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900);
vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
if (vs->lsock == -1) {
fprintf(stderr, "Could not create socket\n");
free(vs->display);
vs->display = NULL;
return -1;
}
reuse_addr = 1; reuse_addr = 1;
ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR, ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
(const char *)&reuse_addr, sizeof(reuse_addr)); (const char *)&reuse_addr, sizeof(reuse_addr));
if (ret == -1) { if (ret == -1) {
fprintf(stderr, "setsockopt() failed\n"); fprintf(stderr, "setsockopt() failed\n");
exit(1); close(vs->lsock);
vs->lsock = -1;
free(vs->display);
vs->display = NULL;
return -1;
} }
} }
if (bind(vs->lsock, addr, addrlen) == -1) { if (bind(vs->lsock, addr, addrlen) == -1) {
fprintf(stderr, "bind() failed\n"); fprintf(stderr, "bind() failed\n");
exit(1); close(vs->lsock);
vs->lsock = -1;
free(vs->display);
vs->display = NULL;
return -1;
} }
if (listen(vs->lsock, 1) == -1) { if (listen(vs->lsock, 1) == -1) {
fprintf(stderr, "listen() failed\n"); fprintf(stderr, "listen() failed\n");
exit(1); close(vs->lsock);
vs->lsock = -1;
free(vs->display);
vs->display = NULL;
return -1;
} }
ret = qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs); return qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);
if (ret == -1) {
exit(1);
}
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment