mirror of
https://github.com/git/git.git
synced 2026-03-13 18:33:25 +01:00
MinGW: Make git native protocol work.
As it turns out, the things returned by Winsock2's socket() are handles that can be passed to ReadFile()/WriteFile() - almost. The way this works is by wrapping those handles into file descriptors with _open_osfhandle(). But it turns out that the sockets created by the plain socket() function are prepared for "overlapped" I/O, which confuses ReadFile()/WriteFile(). Therefore, a reimplementation is provided that uses WSASocket() to explicitly asks for non-overlapped sockets. Special thanks got to H. Peter Anvin, who provided the necessary clues.
This commit is contained in:
@@ -50,14 +50,14 @@ This works:
|
||||
- All the plumbings.
|
||||
- Many porcelains, in particular, checkout, add, rm, commit, diff,
|
||||
branch, merge, rebase, log, show, bisect, grep...
|
||||
- pull, clone, fetch, push via ssh.
|
||||
- pull, clone, fetch, push via native git protocal as well as ssh.
|
||||
- Local pull, clone, fetch, push.
|
||||
- gitk, if invoked as "wish84 <prefix>\bin\gitk", but there are
|
||||
artefacts in its layout.
|
||||
artefacts in its layout. A workaround by Mark Levedahl is in
|
||||
branch 'devel'.
|
||||
|
||||
This does not work:
|
||||
|
||||
- pull, clone, fetch, push via native GIT protocol.
|
||||
- daemon, svn, *import, cvs*
|
||||
- and certainly a lot more that I never have found a need to look at.
|
||||
|
||||
|
||||
@@ -293,3 +293,22 @@ void mingw_execve(const char *cmd, const char **argv, const char **env)
|
||||
exit(ret);
|
||||
}
|
||||
}
|
||||
|
||||
int mingw_socket(int domain, int type, int protocol)
|
||||
{
|
||||
SOCKET s = WSASocket(domain, type, protocol, NULL, 0, 0);
|
||||
if (s == INVALID_SOCKET) {
|
||||
/*
|
||||
* WSAGetLastError() values are regular BSD error codes
|
||||
* biased by WSABASEERR.
|
||||
* However, strerror() does not know about networking
|
||||
* specific errors, which are values beginning at 38 or so.
|
||||
* Therefore, we choose to leave the biased error code
|
||||
* in errno so that _if_ someone looks up the code somewhere,
|
||||
* then it is at least the number that are usually listed.
|
||||
*/
|
||||
errno = WSAGetLastError();
|
||||
return -1;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
16
connect.c
16
connect.c
@@ -527,7 +527,23 @@ static int git_tcp_connect_sock(char *host)
|
||||
|
||||
static void git_tcp_connect(int fd[2], char *host)
|
||||
{
|
||||
#ifndef __MINGW32__
|
||||
int sockfd = git_tcp_connect_sock(host);
|
||||
#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);
|
||||
/* 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);
|
||||
|
||||
@@ -374,6 +374,9 @@ struct tm *localtime_r(const time_t *timep, struct tm *result);
|
||||
char *mingw_getcwd(char *pointer, int len);
|
||||
#define getcwd mingw_getcwd
|
||||
|
||||
int mingw_socket(int domain, int type, int protocol);
|
||||
#define socket mingw_socket
|
||||
|
||||
#define setlinebuf(x)
|
||||
#define fsync(x)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user