Commit fd1dff4b418e28302018f37371dd515150f23534

Authored by bellard
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
... ... @@ -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 */
... ...