From 60db5000ab3307def85fd8e4618e661a565c1750 Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Wed, 21 Nov 2007 22:47:00 +0100 Subject: [PATCH 1/3] 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 --- compat/mingw.c | 29 ++++++++++++++++++++++++++++- git-compat-util.h | 6 ++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/compat/mingw.c b/compat/mingw.c index aa730e9bc1..f2d18a7410 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -631,8 +631,22 @@ void env_unsetenv(char **env, const char *name) env[dst] = NULL; } +/* this is the first function to call into WS_32; initialize it */ +#undef gethostbyname +struct hostent *mingw_gethostbyname(const char *host) +{ + WSADATA wsa; + + if (WSAStartup(MAKEWORD(2,2), &wsa)) + die("unable to initialize winsock subsystem, error %d", + WSAGetLastError()); + atexit((void(*)(void)) WSACleanup); + return gethostbyname(host); +} + int mingw_socket(int domain, int type, int protocol) { + int sockfd; SOCKET s = WSASocket(domain, type, protocol, NULL, 0, 0); if (s == INVALID_SOCKET) { /* @@ -647,7 +661,20 @@ int mingw_socket(int domain, int type, int protocol) errno = WSAGetLastError(); return -1; } - return s; + /* convert into a file descriptor */ + if ((sockfd = _open_osfhandle(s, O_RDWR|O_BINARY)) < 0) { + closesocket(s); + return error("unable to make a socket file descriptor: %s", + strerror(errno)); + } + return sockfd; +} + +#undef connect +int mingw_connect(int sockfd, struct sockaddr *sa, size_t sz) +{ + SOCKET s = (SOCKET)_get_osfhandle(sockfd); + return connect(s, sa, sz); } #undef rename diff --git a/git-compat-util.h b/git-compat-util.h index 74412331d8..1d147af906 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -520,9 +520,15 @@ struct tm *localtime_r(const time_t *timep, struct tm *result); char *mingw_getcwd(char *pointer, int len); #define getcwd mingw_getcwd +struct hostent *mingw_gethostbyname(const char *host); +#define gethostbyname mingw_gethostbyname + int mingw_socket(int domain, int type, int protocol); #define socket mingw_socket +int mingw_connect(int sockfd, struct sockaddr *sa, size_t sz); +#define connect mingw_connect + int mingw_rename(const char*, const char*); #define rename mingw_rename From d0d5661addd02d3aca9e543457f962eacae704a2 Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Wed, 21 Nov 2007 22:48:07 +0100 Subject: [PATCH 2/3] Revert Windows specific code related to Winsock. These things are now hidden behind a compatibility layer. --- connect.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/connect.c b/connect.c index 0f10c40652..82fb62b080 100644 --- a/connect.c +++ b/connect.c @@ -345,23 +345,7 @@ static int git_tcp_connect_sock(char *host, int flags) static void git_tcp_connect(int fd[2], char *host, int flags) { -#ifndef __MINGW32__ int sockfd = git_tcp_connect_sock(host, flags); -#else - int sockfd; - WSADATA wsa; - - if (WSAStartup(MAKEWORD(2,2), &wsa)) - die("unable to initialize winsock subsystem, error %d", - WSAGetLastError()); - atexit((void(*)(void)) WSACleanup); - - sockfd = git_tcp_connect_sock(host, flags); - /* convert into a file descriptor */ - if ((sockfd = _open_osfhandle(sockfd, O_RDWR|O_BINARY)) < 0) - die("unable to make a socket file descriptor: %s", - strerror(errno)); -#endif fd[0] = sockfd; fd[1] = dup(sockfd); From 9c906c8e6c49b0bfa66580a35bcf013ee122970c Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Thu, 22 Nov 2007 22:24:56 +0100 Subject: [PATCH 3/3] Be more careful in splitting the program name from the path. A git program can be invoked using with such a full path name: C:\Src\mingw-git\t\trash/..\..\git-fetch-pack.exe i.e. it can contain both types of path separators. We must pick the one that comes last. Signed-off-by: Johannes Sixt --- git.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/git.c b/git.c index e5fdd04057..04ef05fcf5 100644 --- a/git.c +++ b/git.c @@ -399,8 +399,9 @@ int main(int argc, const char **argv) * if we don't have anything better. */ #ifdef __MINGW32__ - if (!slash) - slash = strrchr(cmd, '\\'); + char *bslash = strrchr(cmd, '\\'); + if (!slash || (bslash && bslash > slash)) + slash = bslash; #endif if (slash) { *slash++ = 0;