18 #ifdef XEMU_HAS_SOCKET_API
22 #include <sys/types.h>
32 #ifndef WINSOCK_VERSION_MAJOR
33 #define WINSOCK_VERSION_MAJOR 2
35 #ifndef WINSOCK_VERSION_MINOR
36 #define WINSOCK_VERSION_MINOR 2
40 # define SOCK_ERR() WSAGetLastError()
42 # define SOCK_ERR() (errno+0)
47 const char *xemusock_strerror (
int err )
50 case 0:
return "Success (0)";
51 case WSA_INVALID_HANDLE:
return "Invalid handle (INVALID_HANDLE)";
52 case WSA_NOT_ENOUGH_MEMORY:
return "Not enough memory (NOT_ENOUGH_MEMORY)";
53 case WSA_INVALID_PARAMETER:
return "Invalid parameter (INVALID_PARAMETER)";
54 case WSA_OPERATION_ABORTED:
return "Operation aborted (OPERATION_ABORTED)";
55 case WSA_IO_INCOMPLETE:
return "IO incomplete (IO_INCOMPLETE)";
56 case WSA_IO_PENDING:
return "IO pending (IO_PENDING)";
57 case WSAEINTR:
return "Interrupted (EINTR)";
58 case WSAEBADF:
return "Invalid handle (EBADF)";
59 case WSAEACCES:
return "Permission denied (EACCES)";
60 case WSAEFAULT:
return "Bad address (EFAULT)";
61 case WSAEINVAL:
return "Invaild argument (EINVAL)";
62 case WSAEMFILE:
return "Too many files (EMFILE)";
63 case WSAEWOULDBLOCK:
return "Resource temporarily unavailable (EWOULDBLOCK)";
64 case WSAEINPROGRESS:
return "Operation now in progress (EINPROGRESS)";
65 case WSAEALREADY:
return "Operation already in progress (EALREADY)";
66 case WSAENOTSOCK:
return "Socket operation on nonsocket (ENOTSOCK)";
67 case WSAEDESTADDRREQ:
return "Destination address required (EDESTADDRREQ)";
68 case WSAEMSGSIZE:
return "Message too long (EMSGSIZE)";
69 case WSAEPROTOTYPE:
return "Protocol wrong type for socket (EPROTOTYPE)";
70 case WSAENOPROTOOPT:
return "Bad protocol option (ENOPROTOOPT)";
71 case WSAEPROTONOSUPPORT:
return "Protocol not supported (EPROTONOSUPPORT)";
72 case WSAESOCKTNOSUPPORT:
return "Socket type not supported (ESOCKTNOSUPPORT)";
73 case WSAEOPNOTSUPP:
return "Operation not supported (EOPNOTSUPP)";
74 case WSAEPFNOSUPPORT:
return "Protocol family not supported (EPFNOSUPPORT)";
75 case WSAEAFNOSUPPORT:
return "Address family not supported by protocol family (EAFNOSUPPORT)";
76 case WSAEADDRINUSE:
return "Address already in use (EADDRINUSE)";
77 case WSAEADDRNOTAVAIL:
return "Cannot assign requested address (EADDRNOTAVAIL)";
78 case WSAENETDOWN:
return "Network is down (ENETDOWN)";
79 case WSAENETUNREACH:
return "Network is unreachable (ENETUNREACH)";
80 case WSAENETRESET:
return "Network dropped connection on reset (ENETRESET)";
81 case WSAECONNABORTED:
return "Software caused connection abort (ECONNABORTED)";
82 case WSAECONNRESET:
return "Connection reset by peer (ECONNRESET)";
83 case WSAENOBUFS:
return "No buffer space available (ENOBUFS)";
84 case WSAEISCONN:
return "Socket is already connected (EISCONN)";
85 case WSAENOTCONN:
return "Socket is not connected (ENOTCONN)";
86 case WSAESHUTDOWN:
return "Cannot send after socket shutdown (ESHUTDOWN)";
87 case WSAETOOMANYREFS:
return "Too many references (ETOOMANYREFS)";
88 case WSAETIMEDOUT:
return "Connection timed out (ETIMEDOUT)";
89 case WSAECONNREFUSED:
return "Connection refused (ECONNREFUSED)";
90 case WSAELOOP:
return "Cannot translate name (ELOOP)";
91 case WSAENAMETOOLONG:
return "Name too long (ENAMETOOLONG)";
92 case WSAEHOSTDOWN:
return "Host is down (EHOSTDOWN)";
93 case WSAEHOSTUNREACH:
return "No route to host (EHOSTUNREACH)";
94 case WSAENOTEMPTY:
return "Directory not empty (ENOTEMPTY)";
95 case WSAEPROCLIM:
return "Too many processes (EPROCLIM)";
96 case WSAEUSERS:
return "User quota exceeded (EUSERS)";
97 case WSAEDQUOT:
return "Disk quota exceeded (EDQUOT)";
98 case WSAESTALE:
return "Stale file handle reference (ESTALE)";
99 case WSAEREMOTE:
return "Item is remote (EREMOTE)";
100 case WSASYSNOTREADY:
return "Network subsystem is unavailable (SYSNOTREADY)";
101 case WSAVERNOTSUPPORTED:
return "Winsock.dll version out of range (VERNOTSUPPORTED)";
102 case WSANOTINITIALISED:
return "Successful WSAStartup not yet performed (NOTINITIALISED)";
103 case WSAEDISCON:
return "Graceful shutdown in progress (EDISCON)";
104 case WSAENOMORE:
return "No more results (ENOMORE)";
105 case WSAECANCELLED:
return "Call has been canceled (WSAECANCELLED)";
106 case WSAEINVALIDPROCTABLE:
return "Procedure call table is invalid (EINVALIDPROCTABLE)";
107 case WSAEINVALIDPROVIDER:
return "Service provider is invalid (EINVALIDPROVIDER)";
108 case WSAEPROVIDERFAILEDINIT:
return "Service provider failed to initialize (EPROVIDERFAILEDINIT)";
109 case WSASYSCALLFAILURE:
return "System call failure (SYSCALLFAILURE)";
110 case WSASERVICE_NOT_FOUND:
return "Service not found (SERVICE_NOT_FOUND)";
111 case WSATYPE_NOT_FOUND:
return "Class type not found (TYPE_NOT_FOUND)";
112 case WSA_E_NO_MORE:
return "No more results (E_NO_MORE)";
113 case WSA_E_CANCELLED:
return "Call was canceled (E_CANCELLED)";
114 case WSAEREFUSED:
return "Database query was refused (EREFUSED)";
115 case WSAHOST_NOT_FOUND:
return "Host not found (HOST_NOT_FOUND)";
116 case WSATRY_AGAIN:
return "Nonauthoritative host not found (TRY_AGAIN)";
117 case WSANO_RECOVERY:
return "This is a nonrecoverable error (NO_RECOVERY)";
118 case WSANO_DATA:
return "Valid name, no data record of requested type (NO_DATA)";
119 default:
return "Unknown Winsock error";
125 static int _winsock_init_status = 1;
126 static char _winsock_errmsg[512];
129 const char *xemusock_init (
void )
131 if (_winsock_init_status == 0)
133 if (_winsock_init_status < 0)
134 return _winsock_errmsg;
137 if (WSAStartup(MAKEWORD(WINSOCK_VERSION_MAJOR, WINSOCK_VERSION_MINOR), &wsa)) {
138 int err = SOCK_ERR();
139 snprintf(_winsock_errmsg,
sizeof _winsock_errmsg,
"WINSOCK: ERROR: Failed to initialize winsock2, [%d]: %s", err, xemusock_strerror(err));
140 _winsock_init_status = -1;
142 return _winsock_errmsg;
144 if (LOBYTE(wsa.wVersion) != WINSOCK_VERSION_MAJOR || HIBYTE(wsa.wVersion) != WINSOCK_VERSION_MINOR) {
146 snprintf(_winsock_errmsg,
sizeof _winsock_errmsg,
147 "WINSOCK: ERROR: No suitable winsock API in the implemantion DLL (we need v%d.%d, we got: v%d.%d), windows system error ...",
148 WINSOCK_VERSION_MAJOR, WINSOCK_VERSION_MINOR,
149 HIBYTE(wsa.wVersion), LOBYTE(wsa.wVersion)
151 _winsock_init_status = -1;
153 return _winsock_errmsg;
155 DEBUGPRINT(
"WINSOCK: OK: initialized, version %d.%d" NL, HIBYTE(wsa.wVersion), LOBYTE(wsa.wVersion));
157 _winsock_init_status = 0;
162 void xemusock_uninit (
void )
165 if (_winsock_init_status == 0) {
167 _winsock_init_status = 1;
174 void xemusock_fill_servaddr_for_inet_ip_netlong (
struct sockaddr_in *servaddr,
unsigned int ip_netlong,
int port )
176 memset(servaddr, 0,
sizeof(
struct sockaddr_in));
178 ip_netlong = INADDR_ANY;
179 servaddr->sin_addr.s_addr = ip_netlong;
180 servaddr->sin_port = htons(port);
181 servaddr->sin_family = AF_INET;
185 void xemusock_fill_servaddr_for_inet_ip_native (
struct sockaddr_in *servaddr,
unsigned int ip_native,
int port )
187 xemusock_fill_servaddr_for_inet_ip_netlong(servaddr, htonl(ip_native), port);
191 int xemusock_set_nonblocking ( xemusock_socket_t sock,
int is_nonblock,
int *xerrno )
194 u_long
mode = !!is_nonblock;
195 if (ioctlsocket(sock, FIONBIO, &mode)) {
197 *xerrno = SOCK_ERR();
202 int flags = fcntl(sock, F_GETFL);
205 *xerrno = SOCK_ERR();
209 if (fcntl(sock, F_SETFL,
flags) == -1) {
211 *xerrno = SOCK_ERR();
219 xemusock_socket_t xemusock_create_for_inet (
int is_tcp,
int is_nonblock,
int *xerrno )
221 xemusock_socket_t sock = socket(AF_INET, is_tcp ? SOCK_STREAM : SOCK_DGRAM, 0);
222 if (sock == XS_INVALID_SOCKET) {
224 *xerrno = SOCK_ERR();
225 return XS_INVALID_SOCKET;
227 if (is_nonblock == 1) {
228 int ret = xemusock_set_nonblocking(sock, 1, xerrno);
230 xemusock_close(sock, NULL);
231 return XS_INVALID_SOCKET;
239 int xemusock_close ( xemusock_socket_t sock,
int *xerrno )
242 int ret = closesocket(sock);
244 int ret = close(sock);
248 *xerrno = SOCK_ERR();
249 return XS_SOCKET_ERROR;
255 int xemusock_connect ( xemusock_socket_t sock,
struct sockaddr_in *servaddr,
int *xerrno )
257 if (connect(sock, (
struct sockaddr *)servaddr,
sizeof(
struct sockaddr_in)) == XS_SOCKET_ERROR) {
259 *xerrno = SOCK_ERR();
266 int xemusock_shutdown ( xemusock_socket_t sock,
int *xerrno )
268 if (shutdown(sock, SHUT_RDWR) == XS_SOCKET_ERROR) {
270 *xerrno = SOCK_ERR();
277 int xemusock_sendto ( xemusock_socket_t sock,
const void *buffer,
int length,
struct sockaddr_in *servaddr,
int *xerrno )
279 int ret = sendto(sock, buffer, length, 0, (
struct sockaddr*)servaddr,
sizeof(
struct sockaddr_in));
280 if (ret == XS_SOCKET_ERROR) {
282 *xerrno = SOCK_ERR();
289 int xemusock_send ( xemusock_socket_t sock,
const void *buffer,
int length,
int *xerrno )
291 int ret = send(sock, buffer, length, 0);
292 if (ret == XS_SOCKET_ERROR) {
294 *xerrno = SOCK_ERR();
301 int xemusock_recvfrom ( xemusock_socket_t sock,
void *buffer,
int length,
struct sockaddr_in *servaddr,
int *xerrno )
303 xemusock_socklen_t addrlen =
sizeof(
struct sockaddr_in);
304 int ret = recvfrom(sock, buffer, length, 0, (
struct sockaddr*)servaddr, &addrlen);
305 if (ret == XS_SOCKET_ERROR) {
307 *xerrno = SOCK_ERR();
314 int xemusock_recv ( xemusock_socket_t sock,
void *buffer,
int length,
int *xerrno )
316 int ret = recv(sock, buffer, length, 0);
317 if (ret == XS_SOCKET_ERROR) {
319 *xerrno = SOCK_ERR();
326 int xemusock_bind ( xemusock_socket_t sock,
struct sockaddr *
addr, xemusock_socklen_t addrlen,
int *xerrno )
328 int ret = bind(sock,
addr, addrlen);
331 *xerrno = SOCK_ERR();
338 int xemusock_listen ( xemusock_socket_t sock,
int backlog,
int *xerrno )
340 int ret = listen(sock, backlog);
343 *xerrno = SOCK_ERR();
350 xemusock_socket_t xemusock_accept ( xemusock_socket_t sock,
struct sockaddr *
addr, xemusock_socklen_t *addrlen,
int *xerrno )
352 xemusock_socket_t ret = accept(sock,
addr, addrlen);
353 if (ret == XS_INVALID_SOCKET) {
355 *xerrno = SOCK_ERR();
361 int xemusock_setsockopt ( xemusock_socket_t sock,
int level,
int option,
const void *
value,
int len,
int *xerrno )
363 if (setsockopt(sock, level, option, (
const char*)
value, len)) {
365 *xerrno = SOCK_ERR();
372 int xemusock_setsockopt_reuseaddr ( xemusock_socket_t sock,
int *xerrno )
375 static const BOOL on = 1;
377 static const int on = 1;
379 return xemusock_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on,
sizeof on, xerrno);
383 int xemusock_select_1 ( xemusock_socket_t sock,
int usec,
int what,
int *xerrno )
387 struct timeval timeout;
388 fd_set fds_r, fds_w, fds_e;
392 if (what & XEMUSOCK_SELECT_R)
393 FD_SET(sock, &fds_r);
394 if (what & XEMUSOCK_SELECT_W)
395 FD_SET(sock, &fds_w);
396 if (what & XEMUSOCK_SELECT_E)
397 FD_SET(sock, &fds_e);
399 timeout.tv_usec = usec;
400 ret = select(sock + 1, &fds_r, &fds_w, &fds_e, usec >= 0 ? &timeout : NULL);
401 if (ret == XS_SOCKET_ERROR) {
402 int err = SOCK_ERR();
406 *xerrno = SOCK_ERR();
411 return (FD_ISSET(sock, &fds_r) ? XEMUSOCK_SELECT_R : 0) | (FD_ISSET(sock, &fds_w) ? XEMUSOCK_SELECT_W : 0) | (FD_ISSET(sock, &fds_e) ? XEMUSOCK_SELECT_E : 0);