@matheusbsbs / matheus-bagliano / commits / 746fb85744
Fork 0

Windows: Implement wrappers for gethostbyname(), socket(), and connect().

gethostbyname() is the first function that calls into the Winsock library, and it is wrapped only to initialize the library. socket() is wrapped for two reasons: - Windows's socket() creates things that are like low-level file handles, and they must be converted into file descriptors first. - And these handles cannot be used with plain ReadFile()/WriteFile() because they are opened for "overlapped IO". We have to use WSASocket() to create non-overlapped IO sockets. connect() must be wrapped because Windows's connect() expects the low-level sockets, not file descriptors, and we must first unwrap the file descriptor before we can pass it on to Windows's connect(). Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>

Johannes Sixt committed Dec 26, 2007 at 13:51 UTC 746fb8574459798d127e3f9cf782ccb8e31c9e45
2 files changed +55
compat/mingw.c
+46
@@ -432,6 +432,52 @@ char **env_setenv(char **env, const char *name)
432 return env;
433 }
434
435 +/* this is the first function to call into WS_32; initialize it */
436 +#undef gethostbyname
437 +struct hostent *mingw_gethostbyname(const char *host)
438 +{
439 + WSADATA wsa;
440 +
441 + if (WSAStartup(MAKEWORD(2,2), &wsa))
442 + die("unable to initialize winsock subsystem, error %d",
443 + WSAGetLastError());
444 + atexit((void(*)(void)) WSACleanup);
445 + return gethostbyname(host);
446 +}
447 +
448 +int mingw_socket(int domain, int type, int protocol)
449 +{
450 + int sockfd;
451 + SOCKET s = WSASocket(domain, type, protocol, NULL, 0, 0);
452 + if (s == INVALID_SOCKET) {
453 + /*
454 + * WSAGetLastError() values are regular BSD error codes
455 + * biased by WSABASEERR.
456 + * However, strerror() does not know about networking
457 + * specific errors, which are values beginning at 38 or so.
458 + * Therefore, we choose to leave the biased error code
459 + * in errno so that _if_ someone looks up the code somewhere,
460 + * then it is at least the number that are usually listed.
461 + */
462 + errno = WSAGetLastError();
463 + return -1;
464 + }
465 + /* convert into a file descriptor */
466 + if ((sockfd = _open_osfhandle(s, O_RDWR|O_BINARY)) < 0) {
467 + closesocket(s);
468 + return error("unable to make a socket file descriptor: %s",
469 + strerror(errno));
470 + }
471 + return sockfd;
472 +}
473 +
474 +#undef connect
475 +int mingw_connect(int sockfd, struct sockaddr *sa, size_t sz)
476 +{
477 + SOCKET s = (SOCKET)_get_osfhandle(sockfd);
478 + return connect(s, sa, sz);
479 +}
480 +
481 #undef rename
482 int mingw_rename(const char *pold, const char *pnew)
483 {
compat/mingw.h
+9
@@ -148,6 +148,15 @@ int mingw_open (const char *filename, int oflags, ...);
148 char *mingw_getcwd(char *pointer, int len);
149 #define getcwd mingw_getcwd
150
151 +struct hostent *mingw_gethostbyname(const char *host);
152 +#define gethostbyname mingw_gethostbyname
153 +
154 +int mingw_socket(int domain, int type, int protocol);
155 +#define socket mingw_socket
156 +
157 +int mingw_connect(int sockfd, struct sockaddr *sa, size_t sz);
158 +#define connect mingw_connect
159 +
160 int mingw_rename(const char*, const char*);
161 #define rename mingw_rename
162