Revision 6ca957f0 vnc.c
b/vnc.c | ||
---|---|---|
1 | 1 |
#include "vl.h" |
2 |
|
|
3 |
#include <sys/socket.h> |
|
4 |
#include <netinet/in.h> |
|
5 |
#include <netinet/tcp.h> |
|
6 |
#include <fcntl.h> |
|
2 |
#include "qemu_socket.h" |
|
7 | 3 |
|
8 | 4 |
#define VNC_REFRESH_INTERVAL (1000 / 30) |
9 | 5 |
|
... | ... | |
386 | 382 |
buffer->offset += len; |
387 | 383 |
} |
388 | 384 |
|
389 |
static int vnc_client_io_error(VncState *vs, int ret) |
|
385 |
static int vnc_client_io_error(VncState *vs, int ret, int last_errno)
|
|
390 | 386 |
{ |
391 | 387 |
if (ret == 0 || ret == -1) { |
392 |
if (ret == -1 && (errno == EINTR || errno == EAGAIN))
|
|
388 |
if (ret == -1 && (last_errno == EINTR || last_errno == EAGAIN))
|
|
393 | 389 |
return 0; |
394 | 390 |
|
395 | 391 |
qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL); |
396 |
close(vs->csock); |
|
392 |
closesocket(vs->csock);
|
|
397 | 393 |
vs->csock = -1; |
398 | 394 |
buffer_reset(&vs->input); |
399 | 395 |
buffer_reset(&vs->output); |
... | ... | |
405 | 401 |
|
406 | 402 |
static void vnc_client_error(VncState *vs) |
407 | 403 |
{ |
408 |
errno = EINVAL; |
|
409 |
vnc_client_io_error(vs, -1); |
|
404 |
vnc_client_io_error(vs, -1, EINVAL); |
|
410 | 405 |
} |
411 | 406 |
|
412 | 407 |
static void vnc_client_write(void *opaque) |
... | ... | |
414 | 409 |
ssize_t ret; |
415 | 410 |
VncState *vs = opaque; |
416 | 411 |
|
417 |
ret = write(vs->csock, vs->output.buffer, vs->output.offset);
|
|
418 |
ret = vnc_client_io_error(vs, ret); |
|
412 |
ret = send(vs->csock, vs->output.buffer, vs->output.offset, 0);
|
|
413 |
ret = vnc_client_io_error(vs, ret, socket_error());
|
|
419 | 414 |
if (!ret) |
420 | 415 |
return; |
421 | 416 |
|
... | ... | |
440 | 435 |
|
441 | 436 |
buffer_reserve(&vs->input, 4096); |
442 | 437 |
|
443 |
ret = read(vs->csock, buffer_end(&vs->input), 4096);
|
|
444 |
ret = vnc_client_io_error(vs, ret); |
|
438 |
ret = recv(vs->csock, buffer_end(&vs->input), 4096, 0);
|
|
439 |
ret = vnc_client_io_error(vs, ret, socket_error());
|
|
445 | 440 |
if (!ret) |
446 | 441 |
return; |
447 | 442 |
|
... | ... | |
812 | 807 |
|
813 | 808 |
vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen); |
814 | 809 |
if (vs->csock != -1) { |
815 |
fcntl(vs->csock, F_SETFL, O_NONBLOCK);
|
|
810 |
socket_set_nonblock(vs->csock);
|
|
816 | 811 |
qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, opaque); |
817 | 812 |
vnc_write(vs, "RFB 003.003\n", 12); |
818 | 813 |
vnc_flush(vs); |
... | ... | |
862 | 857 |
|
863 | 858 |
reuse_addr = 1; |
864 | 859 |
ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR, |
865 |
&reuse_addr, sizeof(reuse_addr)); |
|
860 |
(const char *)&reuse_addr, sizeof(reuse_addr));
|
|
866 | 861 |
if (ret == -1) { |
867 | 862 |
fprintf(stderr, "setsockopt() failed\n"); |
868 | 863 |
exit(1); |
Also available in: Unified diff