Commit fd1dff4b418e28302018f37371dd515150f23534
1 parent
ff3fbb30
win32 socket support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1731 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
209 additions
and
112 deletions
vl.c
| ... | ... | @@ -64,6 +64,8 @@ |
| 64 | 64 | #include <malloc.h> |
| 65 | 65 | #include <sys/timeb.h> |
| 66 | 66 | #include <windows.h> |
| 67 | +#include <winsock2.h> | |
| 68 | +#include <ws2tcpip.h> | |
| 67 | 69 | #define getopt_long_only getopt_long |
| 68 | 70 | #define memalign(align, size) malloc(size) |
| 69 | 71 | #endif |
| ... | ... | @@ -1077,20 +1079,67 @@ CharDriverState *qemu_chr_open_null(void) |
| 1077 | 1079 | return chr; |
| 1078 | 1080 | } |
| 1079 | 1081 | |
| 1080 | -#ifndef _WIN32 | |
| 1082 | +#ifdef _WIN32 | |
| 1081 | 1083 | |
| 1082 | -typedef struct { | |
| 1083 | - int fd_in, fd_out; | |
| 1084 | - IOCanRWHandler *fd_can_read; | |
| 1085 | - IOReadHandler *fd_read; | |
| 1086 | - void *fd_opaque; | |
| 1087 | - int max_size; | |
| 1088 | -} FDCharDriver; | |
| 1084 | +#define socket_error() WSAGetLastError() | |
| 1085 | +#undef EINTR | |
| 1086 | +#define EWOULDBLOCK WSAEWOULDBLOCK | |
| 1087 | +#define EINTR WSAEINTR | |
| 1088 | +#define EINPROGRESS WSAEINPROGRESS | |
| 1089 | 1089 | |
| 1090 | -#define STDIO_MAX_CLIENTS 2 | |
| 1090 | +static void socket_cleanup(void) | |
| 1091 | +{ | |
| 1092 | + WSACleanup(); | |
| 1093 | +} | |
| 1091 | 1094 | |
| 1092 | -static int stdio_nb_clients; | |
| 1093 | -static CharDriverState *stdio_clients[STDIO_MAX_CLIENTS]; | |
| 1095 | +static int socket_init(void) | |
| 1096 | +{ | |
| 1097 | + WSADATA Data; | |
| 1098 | + int ret, err; | |
| 1099 | + | |
| 1100 | + ret = WSAStartup(MAKEWORD(2,2), &Data); | |
| 1101 | + if (ret != 0) { | |
| 1102 | + err = WSAGetLastError(); | |
| 1103 | + fprintf(stderr, "WSAStartup: %d\n", err); | |
| 1104 | + return -1; | |
| 1105 | + } | |
| 1106 | + atexit(socket_cleanup); | |
| 1107 | + return 0; | |
| 1108 | +} | |
| 1109 | + | |
| 1110 | +static int send_all(int fd, const uint8_t *buf, int len1) | |
| 1111 | +{ | |
| 1112 | + int ret, len; | |
| 1113 | + | |
| 1114 | + len = len1; | |
| 1115 | + while (len > 0) { | |
| 1116 | + ret = send(fd, buf, len, 0); | |
| 1117 | + if (ret < 0) { | |
| 1118 | + int errno; | |
| 1119 | + errno = WSAGetLastError(); | |
| 1120 | + if (errno != WSAEWOULDBLOCK) { | |
| 1121 | + return -1; | |
| 1122 | + } | |
| 1123 | + } else if (ret == 0) { | |
| 1124 | + break; | |
| 1125 | + } else { | |
| 1126 | + buf += ret; | |
| 1127 | + len -= ret; | |
| 1128 | + } | |
| 1129 | + } | |
| 1130 | + return len1 - len; | |
| 1131 | +} | |
| 1132 | + | |
| 1133 | +void socket_set_nonblock(int fd) | |
| 1134 | +{ | |
| 1135 | + unsigned long opt = 1; | |
| 1136 | + ioctlsocket(fd, FIONBIO, &opt); | |
| 1137 | +} | |
| 1138 | + | |
| 1139 | +#else | |
| 1140 | + | |
| 1141 | +#define socket_error() errno | |
| 1142 | +#define closesocket(s) close(s) | |
| 1094 | 1143 | |
| 1095 | 1144 | static int unix_write(int fd, const uint8_t *buf, int len1) |
| 1096 | 1145 | { |
| ... | ... | @@ -1112,6 +1161,32 @@ static int unix_write(int fd, const uint8_t *buf, int len1) |
| 1112 | 1161 | return len1 - len; |
| 1113 | 1162 | } |
| 1114 | 1163 | |
| 1164 | +static inline int send_all(int fd, const uint8_t *buf, int len1) | |
| 1165 | +{ | |
| 1166 | + return unix_write(fd, buf, len1); | |
| 1167 | +} | |
| 1168 | + | |
| 1169 | +void socket_set_nonblock(int fd) | |
| 1170 | +{ | |
| 1171 | + fcntl(fd, F_SETFL, O_NONBLOCK); | |
| 1172 | +} | |
| 1173 | +#endif /* !_WIN32 */ | |
| 1174 | + | |
| 1175 | +#ifndef _WIN32 | |
| 1176 | + | |
| 1177 | +typedef struct { | |
| 1178 | + int fd_in, fd_out; | |
| 1179 | + IOCanRWHandler *fd_can_read; | |
| 1180 | + IOReadHandler *fd_read; | |
| 1181 | + void *fd_opaque; | |
| 1182 | + int max_size; | |
| 1183 | +} FDCharDriver; | |
| 1184 | + | |
| 1185 | +#define STDIO_MAX_CLIENTS 2 | |
| 1186 | + | |
| 1187 | +static int stdio_nb_clients; | |
| 1188 | +static CharDriverState *stdio_clients[STDIO_MAX_CLIENTS]; | |
| 1189 | + | |
| 1115 | 1190 | static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len) |
| 1116 | 1191 | { |
| 1117 | 1192 | FDCharDriver *s = chr->opaque; |
| ... | ... | @@ -1617,7 +1692,10 @@ CharDriverState *qemu_chr_open_pty(void) |
| 1617 | 1692 | |
| 1618 | 1693 | CharDriverState *qemu_chr_open(const char *filename) |
| 1619 | 1694 | { |
| 1695 | +#ifndef _WIN32 | |
| 1620 | 1696 | const char *p; |
| 1697 | +#endif | |
| 1698 | + | |
| 1621 | 1699 | if (!strcmp(filename, "vc")) { |
| 1622 | 1700 | return text_console_init(&display_state); |
| 1623 | 1701 | } else if (!strcmp(filename, "null")) { |
| ... | ... | @@ -1731,13 +1809,9 @@ int parse_host_port(struct sockaddr_in *saddr, const char *str) |
| 1731 | 1809 | if (!inet_aton(buf, &saddr->sin_addr)) |
| 1732 | 1810 | return -1; |
| 1733 | 1811 | } else { |
| 1734 | -#ifdef _WIN32 | |
| 1735 | - return -1; | |
| 1736 | -#else | |
| 1737 | 1812 | if ((he = gethostbyname(buf)) == NULL) |
| 1738 | 1813 | return - 1; |
| 1739 | 1814 | saddr->sin_addr = *(struct in_addr *)he->h_addr; |
| 1740 | -#endif | |
| 1741 | 1815 | } |
| 1742 | 1816 | } |
| 1743 | 1817 | port = strtol(p, (char **)&r, 0); |
| ... | ... | @@ -2127,6 +2201,8 @@ static int net_tap_init(VLANState *vlan, const char *ifname1, |
| 2127 | 2201 | return 0; |
| 2128 | 2202 | } |
| 2129 | 2203 | |
| 2204 | +#endif /* !_WIN32 */ | |
| 2205 | + | |
| 2130 | 2206 | /* network connection */ |
| 2131 | 2207 | typedef struct NetSocketState { |
| 2132 | 2208 | VLANClientState *vc; |
| ... | ... | @@ -2150,8 +2226,8 @@ static void net_socket_receive(void *opaque, const uint8_t *buf, int size) |
| 2150 | 2226 | uint32_t len; |
| 2151 | 2227 | len = htonl(size); |
| 2152 | 2228 | |
| 2153 | - unix_write(s->fd, (const uint8_t *)&len, sizeof(len)); | |
| 2154 | - unix_write(s->fd, buf, size); | |
| 2229 | + send_all(s->fd, (const uint8_t *)&len, sizeof(len)); | |
| 2230 | + send_all(s->fd, buf, size); | |
| 2155 | 2231 | } |
| 2156 | 2232 | |
| 2157 | 2233 | static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, int size) |
| ... | ... | @@ -2164,16 +2240,20 @@ static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, int size) |
| 2164 | 2240 | static void net_socket_send(void *opaque) |
| 2165 | 2241 | { |
| 2166 | 2242 | NetSocketState *s = opaque; |
| 2167 | - int l, size; | |
| 2243 | + int l, size, err; | |
| 2168 | 2244 | uint8_t buf1[4096]; |
| 2169 | 2245 | const uint8_t *buf; |
| 2170 | 2246 | |
| 2171 | - size = read(s->fd, buf1, sizeof(buf1)); | |
| 2172 | - if (size < 0) | |
| 2173 | - return; | |
| 2174 | - if (size == 0) { | |
| 2247 | + size = recv(s->fd, buf1, sizeof(buf1), 0); | |
| 2248 | + if (size < 0) { | |
| 2249 | + err = socket_error(); | |
| 2250 | + if (err != EWOULDBLOCK) | |
| 2251 | + goto eoc; | |
| 2252 | + } else if (size == 0) { | |
| 2175 | 2253 | /* end of connection */ |
| 2254 | + eoc: | |
| 2176 | 2255 | qemu_set_fd_handler(s->fd, NULL, NULL, NULL); |
| 2256 | + closesocket(s->fd); | |
| 2177 | 2257 | return; |
| 2178 | 2258 | } |
| 2179 | 2259 | buf = buf1; |
| ... | ... | @@ -2236,7 +2316,8 @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr) |
| 2236 | 2316 | int val, ret; |
| 2237 | 2317 | if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) { |
| 2238 | 2318 | fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) does not contain a multicast address\n", |
| 2239 | - inet_ntoa(mcastaddr->sin_addr), ntohl(mcastaddr->sin_addr.s_addr)); | |
| 2319 | + inet_ntoa(mcastaddr->sin_addr), | |
| 2320 | + (int)ntohl(mcastaddr->sin_addr.s_addr)); | |
| 2240 | 2321 | return -1; |
| 2241 | 2322 | |
| 2242 | 2323 | } |
| ... | ... | @@ -2246,11 +2327,26 @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr) |
| 2246 | 2327 | return -1; |
| 2247 | 2328 | } |
| 2248 | 2329 | |
| 2330 | + val = 1; | |
| 2331 | + ret=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, | |
| 2332 | + (const char *)&val, sizeof(val)); | |
| 2333 | + if (ret < 0) { | |
| 2334 | + perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)"); | |
| 2335 | + goto fail; | |
| 2336 | + } | |
| 2337 | + | |
| 2338 | + ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr)); | |
| 2339 | + if (ret < 0) { | |
| 2340 | + perror("bind"); | |
| 2341 | + goto fail; | |
| 2342 | + } | |
| 2343 | + | |
| 2249 | 2344 | /* Add host to multicast group */ |
| 2250 | 2345 | imr.imr_multiaddr = mcastaddr->sin_addr; |
| 2251 | 2346 | imr.imr_interface.s_addr = htonl(INADDR_ANY); |
| 2252 | 2347 | |
| 2253 | - ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *) &imr, sizeof(struct ip_mreq)); | |
| 2348 | + ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, | |
| 2349 | + (const char *)&imr, sizeof(struct ip_mreq)); | |
| 2254 | 2350 | if (ret < 0) { |
| 2255 | 2351 | perror("setsockopt(IP_ADD_MEMBERSHIP)"); |
| 2256 | 2352 | goto fail; |
| ... | ... | @@ -2258,25 +2354,14 @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr) |
| 2258 | 2354 | |
| 2259 | 2355 | /* Force mcast msgs to loopback (eg. several QEMUs in same host */ |
| 2260 | 2356 | val = 1; |
| 2261 | - ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &val, sizeof(val)); | |
| 2357 | + ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, | |
| 2358 | + (const char *)&val, sizeof(val)); | |
| 2262 | 2359 | if (ret < 0) { |
| 2263 | 2360 | perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)"); |
| 2264 | 2361 | goto fail; |
| 2265 | 2362 | } |
| 2266 | 2363 | |
| 2267 | - ret=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); | |
| 2268 | - if (ret < 0) { | |
| 2269 | - perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)"); | |
| 2270 | - goto fail; | |
| 2271 | - } | |
| 2272 | - | |
| 2273 | - ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr)); | |
| 2274 | - if (ret < 0) { | |
| 2275 | - perror("bind"); | |
| 2276 | - goto fail; | |
| 2277 | - } | |
| 2278 | - | |
| 2279 | - fcntl(fd, F_SETFL, O_NONBLOCK); | |
| 2364 | + socket_set_nonblock(fd); | |
| 2280 | 2365 | return fd; |
| 2281 | 2366 | fail: |
| 2282 | 2367 | if (fd>=0) close(fd); |
| ... | ... | @@ -2371,7 +2456,7 @@ static NetSocketState *net_socket_fd_init(VLANState *vlan, int fd, |
| 2371 | 2456 | { |
| 2372 | 2457 | int so_type=-1, optlen=sizeof(so_type); |
| 2373 | 2458 | |
| 2374 | - if(getsockopt(fd, SOL_SOCKET,SO_TYPE, &so_type, &optlen)< 0) { | |
| 2459 | + if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type, &optlen)< 0) { | |
| 2375 | 2460 | fprintf(stderr, "qemu: error: setsockopt(SO_TYPE) for fd=%d failed\n", fd); |
| 2376 | 2461 | return NULL; |
| 2377 | 2462 | } |
| ... | ... | @@ -2433,11 +2518,11 @@ static int net_socket_listen_init(VLANState *vlan, const char *host_str) |
| 2433 | 2518 | perror("socket"); |
| 2434 | 2519 | return -1; |
| 2435 | 2520 | } |
| 2436 | - fcntl(fd, F_SETFL, O_NONBLOCK); | |
| 2521 | + socket_set_nonblock(fd); | |
| 2437 | 2522 | |
| 2438 | 2523 | /* allow fast reuse */ |
| 2439 | 2524 | val = 1; |
| 2440 | - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); | |
| 2525 | + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val)); | |
| 2441 | 2526 | |
| 2442 | 2527 | ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)); |
| 2443 | 2528 | if (ret < 0) { |
| ... | ... | @@ -2458,7 +2543,7 @@ static int net_socket_listen_init(VLANState *vlan, const char *host_str) |
| 2458 | 2543 | static int net_socket_connect_init(VLANState *vlan, const char *host_str) |
| 2459 | 2544 | { |
| 2460 | 2545 | NetSocketState *s; |
| 2461 | - int fd, connected, ret; | |
| 2546 | + int fd, connected, ret, err; | |
| 2462 | 2547 | struct sockaddr_in saddr; |
| 2463 | 2548 | |
| 2464 | 2549 | if (parse_host_port(&saddr, host_str) < 0) |
| ... | ... | @@ -2469,18 +2554,19 @@ static int net_socket_connect_init(VLANState *vlan, const char *host_str) |
| 2469 | 2554 | perror("socket"); |
| 2470 | 2555 | return -1; |
| 2471 | 2556 | } |
| 2472 | - fcntl(fd, F_SETFL, O_NONBLOCK); | |
| 2557 | + socket_set_nonblock(fd); | |
| 2473 | 2558 | |
| 2474 | 2559 | connected = 0; |
| 2475 | 2560 | for(;;) { |
| 2476 | 2561 | ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr)); |
| 2477 | 2562 | if (ret < 0) { |
| 2478 | - if (errno == EINTR || errno == EAGAIN) { | |
| 2479 | - } else if (errno == EINPROGRESS) { | |
| 2563 | + err = socket_error(); | |
| 2564 | + if (err == EINTR || err == EWOULDBLOCK) { | |
| 2565 | + } else if (err == EINPROGRESS) { | |
| 2480 | 2566 | break; |
| 2481 | 2567 | } else { |
| 2482 | 2568 | perror("connect"); |
| 2483 | - close(fd); | |
| 2569 | + closesocket(fd); | |
| 2484 | 2570 | return -1; |
| 2485 | 2571 | } |
| 2486 | 2572 | } else { |
| ... | ... | @@ -2524,8 +2610,6 @@ static int net_socket_mcast_init(VLANState *vlan, const char *host_str) |
| 2524 | 2610 | |
| 2525 | 2611 | } |
| 2526 | 2612 | |
| 2527 | -#endif /* !_WIN32 */ | |
| 2528 | - | |
| 2529 | 2613 | static int get_param_value(char *buf, int buf_size, |
| 2530 | 2614 | const char *tag, const char *str) |
| 2531 | 2615 | { |
| ... | ... | @@ -2649,6 +2733,7 @@ int net_client_init(const char *str) |
| 2649 | 2733 | ret = net_tap_init(vlan, ifname, setup_script); |
| 2650 | 2734 | } |
| 2651 | 2735 | } else |
| 2736 | +#endif | |
| 2652 | 2737 | if (!strcmp(device, "socket")) { |
| 2653 | 2738 | if (get_param_value(buf, sizeof(buf), "fd", p) > 0) { |
| 2654 | 2739 | int fd; |
| ... | ... | @@ -2667,7 +2752,6 @@ int net_client_init(const char *str) |
| 2667 | 2752 | return -1; |
| 2668 | 2753 | } |
| 2669 | 2754 | } else |
| 2670 | -#endif | |
| 2671 | 2755 | { |
| 2672 | 2756 | fprintf(stderr, "Unknown network device: %s\n", device); |
| 2673 | 2757 | return -1; |
| ... | ... | @@ -2918,6 +3002,7 @@ int qemu_set_fd_handler2(int fd, |
| 2918 | 3002 | break; |
| 2919 | 3003 | if (ioh->fd == fd) { |
| 2920 | 3004 | *pioh = ioh->next; |
| 3005 | + qemu_free(ioh); | |
| 2921 | 3006 | break; |
| 2922 | 3007 | } |
| 2923 | 3008 | pioh = &ioh->next; |
| ... | ... | @@ -3812,80 +3897,88 @@ void qemu_system_powerdown_request(void) |
| 3812 | 3897 | |
| 3813 | 3898 | void main_loop_wait(int timeout) |
| 3814 | 3899 | { |
| 3815 | -#ifndef _WIN32 | |
| 3816 | - struct pollfd ufds[MAX_IO_HANDLERS + 1], *pf; | |
| 3817 | 3900 | IOHandlerRecord *ioh, *ioh_next; |
| 3818 | -#endif | |
| 3819 | - int ret; | |
| 3901 | + fd_set rfds, wfds; | |
| 3902 | + int ret, nfds; | |
| 3903 | + struct timeval tv; | |
| 3820 | 3904 | |
| 3821 | 3905 | #ifdef _WIN32 |
| 3822 | - if (timeout > 0) | |
| 3823 | - Sleep(timeout); | |
| 3906 | + /* XXX: see how to merge it with the select. The constraint is | |
| 3907 | + that the select must be interrupted by the timer */ | |
| 3908 | + if (timeout > 0) | |
| 3909 | + Sleep(timeout); | |
| 3910 | +#endif | |
| 3911 | + /* poll any events */ | |
| 3912 | + /* XXX: separate device handlers from system ones */ | |
| 3913 | + nfds = -1; | |
| 3914 | + FD_ZERO(&rfds); | |
| 3915 | + FD_ZERO(&wfds); | |
| 3916 | + for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) { | |
| 3917 | + if (ioh->fd_read && | |
| 3918 | + (!ioh->fd_read_poll || | |
| 3919 | + ioh->fd_read_poll(ioh->opaque) != 0)) { | |
| 3920 | + FD_SET(ioh->fd, &rfds); | |
| 3921 | + if (ioh->fd > nfds) | |
| 3922 | + nfds = ioh->fd; | |
| 3923 | + } | |
| 3924 | + if (ioh->fd_write) { | |
| 3925 | + FD_SET(ioh->fd, &wfds); | |
| 3926 | + if (ioh->fd > nfds) | |
| 3927 | + nfds = ioh->fd; | |
| 3928 | + } | |
| 3929 | + } | |
| 3930 | + | |
| 3931 | + tv.tv_sec = 0; | |
| 3932 | +#ifdef _WIN32 | |
| 3933 | + tv.tv_usec = 0; | |
| 3824 | 3934 | #else |
| 3825 | - /* poll any events */ | |
| 3826 | - /* XXX: separate device handlers from system ones */ | |
| 3827 | - pf = ufds; | |
| 3828 | - for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) { | |
| 3829 | - pf->events = 0; | |
| 3830 | - pf->fd = ioh->fd; | |
| 3831 | - if (ioh->fd_read && | |
| 3832 | - (!ioh->fd_read_poll || | |
| 3833 | - ioh->fd_read_poll(ioh->opaque) != 0)) { | |
| 3834 | - pf->events |= POLLIN; | |
| 3935 | + tv.tv_usec = timeout * 1000; | |
| 3936 | +#endif | |
| 3937 | + ret = select(nfds + 1, &rfds, &wfds, NULL, &tv); | |
| 3938 | + if (ret > 0) { | |
| 3939 | + /* XXX: better handling of removal */ | |
| 3940 | + for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) { | |
| 3941 | + ioh_next = ioh->next; | |
| 3942 | + if (FD_ISSET(ioh->fd, &rfds)) { | |
| 3943 | + ioh->fd_read(ioh->opaque); | |
| 3835 | 3944 | } |
| 3836 | - if (ioh->fd_write) { | |
| 3837 | - pf->events |= POLLOUT; | |
| 3945 | + if (FD_ISSET(ioh->fd, &wfds)) { | |
| 3946 | + ioh->fd_write(ioh->opaque); | |
| 3838 | 3947 | } |
| 3839 | - ioh->ufd = pf; | |
| 3840 | - pf++; | |
| 3841 | 3948 | } |
| 3842 | - | |
| 3843 | - ret = poll(ufds, pf - ufds, timeout); | |
| 3844 | - if (ret > 0) { | |
| 3845 | - /* XXX: better handling of removal */ | |
| 3846 | - for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) { | |
| 3847 | - ioh_next = ioh->next; | |
| 3848 | - pf = ioh->ufd; | |
| 3849 | - if (pf->revents & POLLIN) { | |
| 3850 | - ioh->fd_read(ioh->opaque); | |
| 3851 | - } | |
| 3852 | - if (pf->revents & POLLOUT) { | |
| 3853 | - ioh->fd_write(ioh->opaque); | |
| 3854 | - } | |
| 3855 | - } | |
| 3856 | - } | |
| 3857 | -#endif /* !defined(_WIN32) */ | |
| 3949 | + } | |
| 3950 | + | |
| 3858 | 3951 | #if defined(CONFIG_SLIRP) |
| 3859 | - /* XXX: merge with poll() */ | |
| 3860 | - if (slirp_inited) { | |
| 3861 | - fd_set rfds, wfds, xfds; | |
| 3862 | - int nfds; | |
| 3863 | - struct timeval tv; | |
| 3864 | - | |
| 3865 | - nfds = -1; | |
| 3866 | - FD_ZERO(&rfds); | |
| 3867 | - FD_ZERO(&wfds); | |
| 3868 | - FD_ZERO(&xfds); | |
| 3869 | - slirp_select_fill(&nfds, &rfds, &wfds, &xfds); | |
| 3870 | - tv.tv_sec = 0; | |
| 3871 | - tv.tv_usec = 0; | |
| 3872 | - ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv); | |
| 3873 | - if (ret >= 0) { | |
| 3874 | - slirp_select_poll(&rfds, &wfds, &xfds); | |
| 3875 | - } | |
| 3952 | + /* XXX: merge with the previous select() */ | |
| 3953 | + if (slirp_inited) { | |
| 3954 | + fd_set rfds, wfds, xfds; | |
| 3955 | + int nfds; | |
| 3956 | + struct timeval tv; | |
| 3957 | + | |
| 3958 | + nfds = -1; | |
| 3959 | + FD_ZERO(&rfds); | |
| 3960 | + FD_ZERO(&wfds); | |
| 3961 | + FD_ZERO(&xfds); | |
| 3962 | + slirp_select_fill(&nfds, &rfds, &wfds, &xfds); | |
| 3963 | + tv.tv_sec = 0; | |
| 3964 | + tv.tv_usec = 0; | |
| 3965 | + ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv); | |
| 3966 | + if (ret >= 0) { | |
| 3967 | + slirp_select_poll(&rfds, &wfds, &xfds); | |
| 3876 | 3968 | } |
| 3969 | + } | |
| 3877 | 3970 | #endif |
| 3878 | 3971 | |
| 3879 | - if (vm_running) { | |
| 3880 | - qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL], | |
| 3881 | - qemu_get_clock(vm_clock)); | |
| 3882 | - /* run dma transfers, if any */ | |
| 3883 | - DMA_run(); | |
| 3884 | - } | |
| 3885 | - | |
| 3886 | - /* real time timers */ | |
| 3887 | - qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME], | |
| 3888 | - qemu_get_clock(rt_clock)); | |
| 3972 | + if (vm_running) { | |
| 3973 | + qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL], | |
| 3974 | + qemu_get_clock(vm_clock)); | |
| 3975 | + /* run dma transfers, if any */ | |
| 3976 | + DMA_run(); | |
| 3977 | + } | |
| 3978 | + | |
| 3979 | + /* real time timers */ | |
| 3980 | + qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME], | |
| 3981 | + qemu_get_clock(rt_clock)); | |
| 3889 | 3982 | } |
| 3890 | 3983 | |
| 3891 | 3984 | static CPUState *cur_cpu; |
| ... | ... | @@ -4807,6 +4900,10 @@ int main(int argc, char **argv) |
| 4807 | 4900 | setvbuf(stdout, NULL, _IOLBF, 0); |
| 4808 | 4901 | #endif |
| 4809 | 4902 | |
| 4903 | +#ifdef _WIN32 | |
| 4904 | + socket_init(); | |
| 4905 | +#endif | |
| 4906 | + | |
| 4810 | 4907 | /* init network clients */ |
| 4811 | 4908 | if (nb_net_clients == 0) { |
| 4812 | 4909 | /* if no clients, we use a default config */ | ... | ... |