rugged 1.6.5 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (182) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rugged/rugged_allocator.c +0 -54
  3. data/lib/rugged/version.rb +1 -1
  4. data/vendor/libgit2/CMakeLists.txt +3 -8
  5. data/vendor/libgit2/cmake/CheckPrototypeDefinitionSafe.cmake +16 -0
  6. data/vendor/libgit2/cmake/SelectGSSAPI.cmake +3 -3
  7. data/vendor/libgit2/cmake/SelectHTTPSBackend.cmake +21 -2
  8. data/vendor/libgit2/cmake/SelectHashes.cmake +4 -0
  9. data/vendor/libgit2/cmake/SelectXdiff.cmake +9 -0
  10. data/vendor/libgit2/deps/pcre/LICENCE +5 -5
  11. data/vendor/libgit2/deps/pcre/pcre.h +2 -2
  12. data/vendor/libgit2/deps/pcre/pcre_compile.c +6 -3
  13. data/vendor/libgit2/deps/pcre/pcre_exec.c +2 -2
  14. data/vendor/libgit2/deps/xdiff/CMakeLists.txt +28 -0
  15. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/git-xdiff.h +4 -1
  16. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiffi.c +19 -18
  17. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiffi.h +2 -4
  18. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xemit.c +3 -3
  19. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xhistogram.c +7 -18
  20. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xmacros.h +18 -1
  21. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xmerge.c +24 -22
  22. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xpatience.c +21 -30
  23. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xprepare.c +13 -30
  24. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xutils.c +18 -1
  25. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xutils.h +2 -1
  26. data/vendor/libgit2/include/git2/common.h +26 -1
  27. data/vendor/libgit2/include/git2/diff.h +41 -3
  28. data/vendor/libgit2/include/git2/errors.h +4 -2
  29. data/vendor/libgit2/include/git2/index.h +9 -0
  30. data/vendor/libgit2/include/git2/oid.h +1 -1
  31. data/vendor/libgit2/include/git2/remote.h +18 -0
  32. data/vendor/libgit2/include/git2/repository.h +12 -2
  33. data/vendor/libgit2/include/git2/sys/alloc.h +0 -34
  34. data/vendor/libgit2/include/git2/sys/commit_graph.h +12 -2
  35. data/vendor/libgit2/include/git2/sys/midx.h +5 -1
  36. data/vendor/libgit2/include/git2/sys/stream.h +16 -2
  37. data/vendor/libgit2/include/git2/sys/transport.h +20 -2
  38. data/vendor/libgit2/include/git2/version.h +4 -4
  39. data/vendor/libgit2/include/git2/worktree.h +3 -1
  40. data/vendor/libgit2/src/CMakeLists.txt +34 -11
  41. data/vendor/libgit2/src/cli/cmd_clone.c +22 -6
  42. data/vendor/libgit2/src/cli/progress.c +9 -8
  43. data/vendor/libgit2/src/cli/progress.h +4 -4
  44. data/vendor/libgit2/src/libgit2/CMakeLists.txt +1 -19
  45. data/vendor/libgit2/src/libgit2/annotated_commit.c +2 -2
  46. data/vendor/libgit2/src/libgit2/annotated_commit.h +1 -1
  47. data/vendor/libgit2/src/libgit2/apply.c +4 -3
  48. data/vendor/libgit2/src/libgit2/blame.c +23 -16
  49. data/vendor/libgit2/src/libgit2/blame_git.c +0 -1
  50. data/vendor/libgit2/src/libgit2/branch.c +2 -2
  51. data/vendor/libgit2/src/libgit2/cherrypick.c +3 -3
  52. data/vendor/libgit2/src/libgit2/clone.c +3 -1
  53. data/vendor/libgit2/src/libgit2/commit.c +31 -9
  54. data/vendor/libgit2/src/libgit2/commit_graph.c +110 -43
  55. data/vendor/libgit2/src/libgit2/commit_graph.h +20 -4
  56. data/vendor/libgit2/src/libgit2/commit_list.c +12 -5
  57. data/vendor/libgit2/src/libgit2/commit_list.h +1 -0
  58. data/vendor/libgit2/src/libgit2/config_file.c +14 -8
  59. data/vendor/libgit2/src/libgit2/describe.c +10 -7
  60. data/vendor/libgit2/src/libgit2/diff.c +16 -7
  61. data/vendor/libgit2/src/libgit2/diff.h +6 -6
  62. data/vendor/libgit2/src/libgit2/diff_file.c +7 -7
  63. data/vendor/libgit2/src/libgit2/diff_generate.c +36 -15
  64. data/vendor/libgit2/src/libgit2/diff_parse.c +20 -4
  65. data/vendor/libgit2/src/libgit2/diff_print.c +26 -7
  66. data/vendor/libgit2/src/libgit2/diff_tform.c +4 -4
  67. data/vendor/libgit2/src/libgit2/diff_xdiff.h +1 -1
  68. data/vendor/libgit2/src/libgit2/email.c +4 -3
  69. data/vendor/libgit2/src/libgit2/errors.c +73 -18
  70. data/vendor/libgit2/src/libgit2/fetch.c +37 -9
  71. data/vendor/libgit2/src/libgit2/fetch.h +0 -2
  72. data/vendor/libgit2/src/libgit2/fetchhead.c +11 -9
  73. data/vendor/libgit2/src/libgit2/grafts.c +272 -0
  74. data/vendor/libgit2/src/libgit2/grafts.h +36 -0
  75. data/vendor/libgit2/src/libgit2/ident.c +3 -3
  76. data/vendor/libgit2/src/libgit2/index.c +325 -125
  77. data/vendor/libgit2/src/libgit2/index.h +14 -1
  78. data/vendor/libgit2/src/libgit2/indexer.c +10 -3
  79. data/vendor/libgit2/src/libgit2/iterator.c +20 -5
  80. data/vendor/libgit2/src/libgit2/iterator.h +3 -0
  81. data/vendor/libgit2/src/libgit2/libgit2.c +39 -0
  82. data/vendor/libgit2/src/libgit2/merge.c +14 -9
  83. data/vendor/libgit2/src/libgit2/merge_file.c +0 -2
  84. data/vendor/libgit2/src/libgit2/midx.c +66 -37
  85. data/vendor/libgit2/src/libgit2/midx.h +13 -3
  86. data/vendor/libgit2/src/libgit2/notes.c +9 -8
  87. data/vendor/libgit2/src/libgit2/object.c +40 -15
  88. data/vendor/libgit2/src/libgit2/object.h +6 -0
  89. data/vendor/libgit2/src/libgit2/odb.c +11 -5
  90. data/vendor/libgit2/src/libgit2/odb_pack.c +16 -3
  91. data/vendor/libgit2/src/libgit2/oid.c +7 -1
  92. data/vendor/libgit2/src/libgit2/oidarray.c +49 -3
  93. data/vendor/libgit2/src/libgit2/oidarray.h +5 -1
  94. data/vendor/libgit2/src/libgit2/pack-objects.c +19 -12
  95. data/vendor/libgit2/src/libgit2/pack-objects.h +5 -2
  96. data/vendor/libgit2/src/libgit2/pack.c +3 -3
  97. data/vendor/libgit2/src/libgit2/parse.c +7 -4
  98. data/vendor/libgit2/src/libgit2/parse.h +1 -1
  99. data/vendor/libgit2/src/libgit2/patch.h +7 -1
  100. data/vendor/libgit2/src/libgit2/patch_generate.c +24 -5
  101. data/vendor/libgit2/src/libgit2/patch_parse.c +16 -8
  102. data/vendor/libgit2/src/libgit2/push.c +2 -2
  103. data/vendor/libgit2/src/libgit2/reader.c +1 -1
  104. data/vendor/libgit2/src/libgit2/rebase.c +72 -84
  105. data/vendor/libgit2/src/libgit2/refdb_fs.c +22 -13
  106. data/vendor/libgit2/src/libgit2/refs.c +8 -1
  107. data/vendor/libgit2/src/libgit2/remote.c +15 -6
  108. data/vendor/libgit2/src/libgit2/remote.h +1 -0
  109. data/vendor/libgit2/src/libgit2/repository.c +580 -301
  110. data/vendor/libgit2/src/libgit2/repository.h +17 -2
  111. data/vendor/libgit2/src/libgit2/reset.c +2 -2
  112. data/vendor/libgit2/src/libgit2/revert.c +8 -11
  113. data/vendor/libgit2/src/libgit2/revparse.c +1 -4
  114. data/vendor/libgit2/src/libgit2/revwalk.c +26 -4
  115. data/vendor/libgit2/src/libgit2/stash.c +9 -8
  116. data/vendor/libgit2/src/libgit2/streams/mbedtls.c +0 -1
  117. data/vendor/libgit2/src/libgit2/streams/openssl.c +8 -16
  118. data/vendor/libgit2/src/libgit2/streams/schannel.c +715 -0
  119. data/vendor/libgit2/src/libgit2/streams/schannel.h +28 -0
  120. data/vendor/libgit2/src/libgit2/streams/socket.c +237 -51
  121. data/vendor/libgit2/src/libgit2/streams/socket.h +3 -1
  122. data/vendor/libgit2/src/libgit2/streams/stransport.c +40 -12
  123. data/vendor/libgit2/src/libgit2/streams/tls.c +5 -0
  124. data/vendor/libgit2/src/libgit2/submodule.h +3 -3
  125. data/vendor/libgit2/src/libgit2/threadstate.c +15 -2
  126. data/vendor/libgit2/src/libgit2/threadstate.h +1 -3
  127. data/vendor/libgit2/src/libgit2/transports/auth.h +1 -2
  128. data/vendor/libgit2/src/libgit2/transports/{auth_negotiate.c → auth_gssapi.c} +32 -32
  129. data/vendor/libgit2/src/libgit2/transports/auth_negotiate.h +1 -1
  130. data/vendor/libgit2/src/libgit2/transports/auth_ntlm.h +1 -1
  131. data/vendor/libgit2/src/libgit2/transports/{auth_ntlm.c → auth_ntlmclient.c} +12 -12
  132. data/vendor/libgit2/src/libgit2/transports/auth_sspi.c +341 -0
  133. data/vendor/libgit2/src/libgit2/transports/git.c +7 -8
  134. data/vendor/libgit2/src/libgit2/transports/http.c +7 -2
  135. data/vendor/libgit2/src/libgit2/transports/httpclient.c +5 -0
  136. data/vendor/libgit2/src/libgit2/transports/local.c +13 -4
  137. data/vendor/libgit2/src/libgit2/transports/smart.c +33 -27
  138. data/vendor/libgit2/src/libgit2/transports/smart.h +23 -8
  139. data/vendor/libgit2/src/libgit2/transports/smart_pkt.c +136 -17
  140. data/vendor/libgit2/src/libgit2/transports/smart_protocol.c +154 -47
  141. data/vendor/libgit2/src/libgit2/transports/ssh.c +3 -3
  142. data/vendor/libgit2/src/libgit2/transports/winhttp.c +14 -15
  143. data/vendor/libgit2/src/libgit2/tree-cache.c +26 -16
  144. data/vendor/libgit2/src/libgit2/tree-cache.h +5 -3
  145. data/vendor/libgit2/src/libgit2/tree.c +1 -1
  146. data/vendor/libgit2/src/libgit2/worktree.c +25 -10
  147. data/vendor/libgit2/src/util/alloc.c +65 -6
  148. data/vendor/libgit2/src/util/alloc.h +34 -9
  149. data/vendor/libgit2/src/util/allocators/failalloc.c +0 -60
  150. data/vendor/libgit2/src/util/allocators/failalloc.h +0 -6
  151. data/vendor/libgit2/src/util/allocators/stdalloc.c +2 -105
  152. data/vendor/libgit2/src/util/allocators/win32_leakcheck.c +0 -68
  153. data/vendor/libgit2/src/util/array.h +6 -1
  154. data/vendor/libgit2/src/util/cc-compat.h +2 -0
  155. data/vendor/libgit2/src/util/filebuf.c +6 -1
  156. data/vendor/libgit2/src/util/filebuf.h +19 -6
  157. data/vendor/libgit2/src/util/fs_path.c +1 -1
  158. data/vendor/libgit2/src/util/futils.c +8 -5
  159. data/vendor/libgit2/src/util/git2_features.h.in +9 -3
  160. data/vendor/libgit2/src/util/net.c +308 -157
  161. data/vendor/libgit2/src/util/net.h +25 -0
  162. data/vendor/libgit2/src/util/posix.c +54 -0
  163. data/vendor/libgit2/src/util/posix.h +22 -0
  164. data/vendor/libgit2/src/util/rand.c +6 -4
  165. data/vendor/libgit2/src/util/staticstr.h +66 -0
  166. data/vendor/libgit2/src/util/util.c +15 -10
  167. data/vendor/libgit2/src/util/util.h +24 -16
  168. data/vendor/libgit2/src/util/win32/error.c +1 -1
  169. data/vendor/libgit2/src/util/win32/path_w32.c +8 -8
  170. data/vendor/libgit2/src/util/win32/posix_w32.c +1 -1
  171. data/vendor/libgit2/src/util/win32/utf-conv.c +73 -75
  172. data/vendor/libgit2/src/util/win32/utf-conv.h +81 -14
  173. data/vendor/libgit2/src/util/win32/w32_util.c +1 -1
  174. metadata +29 -23
  175. data/vendor/libgit2/cmake/SelectWinHTTP.cmake +0 -17
  176. data/vendor/libgit2/src/libgit2/netops.c +0 -124
  177. data/vendor/libgit2/src/libgit2/netops.h +0 -68
  178. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiff.h +0 -0
  179. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xemit.h +0 -0
  180. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xinclude.h +0 -0
  181. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xprepare.h +0 -0
  182. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xtypes.h +0 -0
@@ -0,0 +1,28 @@
1
+ /*
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
+ *
4
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
5
+ * a Linking Exception. For full terms see the included COPYING file.
6
+ */
7
+ #ifndef INCLUDE_steams_schannel_h__
8
+ #define INCLUDE_steams_schannel_h__
9
+
10
+ #include "common.h"
11
+
12
+ #include "git2/sys/stream.h"
13
+
14
+ #ifdef GIT_SCHANNEL
15
+
16
+ extern int git_schannel_stream_new(
17
+ git_stream **out,
18
+ const char *host,
19
+ const char *port);
20
+
21
+ extern int git_schannel_stream_wrap(
22
+ git_stream **out,
23
+ git_stream *in,
24
+ const char *host);
25
+
26
+ #endif
27
+
28
+ #endif
@@ -8,26 +8,29 @@
8
8
  #include "streams/socket.h"
9
9
 
10
10
  #include "posix.h"
11
- #include "netops.h"
12
11
  #include "registry.h"
12
+ #include "runtime.h"
13
13
  #include "stream.h"
14
14
 
15
15
  #ifndef _WIN32
16
- # include <sys/types.h>
17
- # include <sys/socket.h>
18
- # include <sys/select.h>
19
- # include <sys/time.h>
20
- # include <netdb.h>
21
- # include <netinet/in.h>
22
- # include <arpa/inet.h>
16
+ # include <sys/types.h>
17
+ # include <sys/socket.h>
18
+ # include <sys/select.h>
19
+ # include <sys/time.h>
20
+ # include <netdb.h>
21
+ # include <netinet/in.h>
22
+ # include <arpa/inet.h>
23
23
  #else
24
- # include <winsock2.h>
25
- # include <ws2tcpip.h>
26
- # ifdef _MSC_VER
27
- # pragma comment(lib, "ws2_32")
28
- # endif
24
+ # include <winsock2.h>
25
+ # include <ws2tcpip.h>
26
+ # ifdef _MSC_VER
27
+ # pragma comment(lib, "ws2_32")
28
+ # endif
29
29
  #endif
30
30
 
31
+ int git_socket_stream__connect_timeout = 0;
32
+ int git_socket_stream__timeout = 0;
33
+
31
34
  #ifdef GIT_WIN32
32
35
  static void net_set_error(const char *str)
33
36
  {
@@ -54,11 +57,8 @@ static int close_socket(GIT_SOCKET s)
54
57
  return 0;
55
58
 
56
59
  #ifdef GIT_WIN32
57
- if (SOCKET_ERROR == closesocket(s))
58
- return -1;
59
-
60
- if (0 != WSACleanup()) {
61
- git_error_set(GIT_ERROR_OS, "winsock cleanup failed");
60
+ if (closesocket(s) != 0) {
61
+ net_set_error("could not close socket");
62
62
  return -1;
63
63
  }
64
64
 
@@ -69,38 +69,119 @@ static int close_socket(GIT_SOCKET s)
69
69
 
70
70
  }
71
71
 
72
- static int socket_connect(git_stream *stream)
72
+ static int set_nonblocking(GIT_SOCKET s)
73
73
  {
74
- struct addrinfo *info = NULL, *p;
75
- struct addrinfo hints;
76
- git_socket_stream *st = (git_socket_stream *) stream;
77
- GIT_SOCKET s = INVALID_SOCKET;
78
- int ret;
79
-
80
74
  #ifdef GIT_WIN32
81
- /* on win32, the WSA context needs to be initialized
82
- * before any socket calls can be performed */
83
- WSADATA wsd;
75
+ unsigned long nonblocking = 1;
84
76
 
85
- if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) {
86
- git_error_set(GIT_ERROR_OS, "winsock init failed");
77
+ if (ioctlsocket(s, FIONBIO, &nonblocking) != 0) {
78
+ net_set_error("could not set socket non-blocking");
87
79
  return -1;
88
80
  }
81
+ #else
82
+ int flags;
83
+
84
+ if ((flags = fcntl(s, F_GETFL, 0)) == -1) {
85
+ net_set_error("could not query socket flags");
86
+ return -1;
87
+ }
88
+
89
+ flags |= O_NONBLOCK;
89
90
 
90
- if (LOBYTE(wsd.wVersion) != 2 || HIBYTE(wsd.wVersion) != 2) {
91
- WSACleanup();
92
- git_error_set(GIT_ERROR_OS, "winsock init failed");
91
+ if (fcntl(s, F_SETFL, flags) != 0) {
92
+ net_set_error("could not set socket non-blocking");
93
93
  return -1;
94
94
  }
95
95
  #endif
96
96
 
97
+ return 0;
98
+ }
99
+
100
+ /* Promote a sockerr to an errno for our error handling routines */
101
+ static int handle_sockerr(GIT_SOCKET socket)
102
+ {
103
+ int sockerr;
104
+ socklen_t errlen = sizeof(sockerr);
105
+
106
+ if (getsockopt(socket, SOL_SOCKET, SO_ERROR,
107
+ (void *)&sockerr, &errlen) < 0)
108
+ return -1;
109
+
110
+ if (sockerr == ETIMEDOUT)
111
+ return GIT_TIMEOUT;
112
+
113
+ errno = sockerr;
114
+ return -1;
115
+ }
116
+
117
+ GIT_INLINE(bool) connect_would_block(int error)
118
+ {
119
+ #ifdef GIT_WIN32
120
+ if (error == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK)
121
+ return true;
122
+ #endif
123
+
124
+ if (error == -1 && errno == EINPROGRESS)
125
+ return true;
126
+
127
+ return false;
128
+ }
129
+
130
+ static int connect_with_timeout(
131
+ GIT_SOCKET socket,
132
+ const struct sockaddr *address,
133
+ socklen_t address_len,
134
+ int timeout)
135
+ {
136
+ struct pollfd fd;
137
+ int error;
138
+
139
+ if (timeout && (error = set_nonblocking(socket)) < 0)
140
+ return error;
141
+
142
+ error = connect(socket, address, address_len);
143
+
144
+ if (error == 0 || !connect_would_block(error))
145
+ return error;
146
+
147
+ fd.fd = socket;
148
+ fd.events = POLLOUT;
149
+ fd.revents = 0;
150
+
151
+ error = p_poll(&fd, 1, timeout);
152
+
153
+ if (error == 0) {
154
+ return GIT_TIMEOUT;
155
+ } else if (error != 1) {
156
+ return -1;
157
+ } else if ((fd.revents & (POLLPRI | POLLHUP | POLLERR))) {
158
+ return handle_sockerr(socket);
159
+ } else if ((fd.revents & POLLOUT) != POLLOUT) {
160
+ git_error_set(GIT_ERROR_NET,
161
+ "unknown error while polling for connect: %d",
162
+ fd.revents);
163
+ return -1;
164
+ }
165
+
166
+ return 0;
167
+ }
168
+
169
+ static int socket_connect(git_stream *stream)
170
+ {
171
+ git_socket_stream *st = (git_socket_stream *) stream;
172
+ GIT_SOCKET s = INVALID_SOCKET;
173
+ struct addrinfo *info = NULL, *p;
174
+ struct addrinfo hints;
175
+ int error;
176
+
97
177
  memset(&hints, 0x0, sizeof(struct addrinfo));
98
178
  hints.ai_socktype = SOCK_STREAM;
99
179
  hints.ai_family = AF_UNSPEC;
100
180
 
101
- if ((ret = p_getaddrinfo(st->host, st->port, &hints, &info)) != 0) {
181
+ if ((error = p_getaddrinfo(st->host, st->port, &hints, &info)) != 0) {
102
182
  git_error_set(GIT_ERROR_NET,
103
- "failed to resolve address for %s: %s", st->host, p_gai_strerror(ret));
183
+ "failed to resolve address for %s: %s",
184
+ st->host, p_gai_strerror(error));
104
185
  return -1;
105
186
  }
106
187
 
@@ -110,51 +191,115 @@ static int socket_connect(git_stream *stream)
110
191
  if (s == INVALID_SOCKET)
111
192
  continue;
112
193
 
113
- if (connect(s, p->ai_addr, (socklen_t)p->ai_addrlen) == 0)
194
+ error = connect_with_timeout(s, p->ai_addr,
195
+ (socklen_t)p->ai_addrlen,
196
+ st->parent.connect_timeout);
197
+
198
+ if (error == 0)
114
199
  break;
115
200
 
116
201
  /* If we can't connect, try the next one */
117
202
  close_socket(s);
118
203
  s = INVALID_SOCKET;
204
+
205
+ if (error == GIT_TIMEOUT)
206
+ break;
119
207
  }
120
208
 
121
209
  /* Oops, we couldn't connect to any address */
122
- if (s == INVALID_SOCKET && p == NULL) {
123
- git_error_set(GIT_ERROR_OS, "failed to connect to %s", st->host);
124
- p_freeaddrinfo(info);
125
- return -1;
210
+ if (s == INVALID_SOCKET) {
211
+ if (error == GIT_TIMEOUT)
212
+ git_error_set(GIT_ERROR_NET, "failed to connect to %s: Operation timed out", st->host);
213
+ else
214
+ git_error_set(GIT_ERROR_OS, "failed to connect to %s", st->host);
215
+ error = -1;
216
+ goto done;
126
217
  }
127
218
 
219
+ if (st->parent.timeout && !st->parent.connect_timeout &&
220
+ (error = set_nonblocking(s)) < 0)
221
+ return error;
222
+
128
223
  st->s = s;
224
+ error = 0;
225
+
226
+ done:
129
227
  p_freeaddrinfo(info);
130
- return 0;
228
+ return error;
131
229
  }
132
230
 
133
- static ssize_t socket_write(git_stream *stream, const char *data, size_t len, int flags)
231
+ static ssize_t socket_write(
232
+ git_stream *stream,
233
+ const char *data,
234
+ size_t len,
235
+ int flags)
134
236
  {
135
237
  git_socket_stream *st = (git_socket_stream *) stream;
136
- ssize_t written;
238
+ struct pollfd fd;
239
+ ssize_t ret;
137
240
 
138
241
  GIT_ASSERT(flags == 0);
139
242
  GIT_UNUSED(flags);
140
243
 
141
- errno = 0;
244
+ ret = p_send(st->s, data, len, 0);
142
245
 
143
- if ((written = p_send(st->s, data, len, 0)) < 0) {
144
- net_set_error("error sending data");
246
+ if (st->parent.timeout && ret < 0 &&
247
+ (errno == EAGAIN || errno != EWOULDBLOCK)) {
248
+ fd.fd = st->s;
249
+ fd.events = POLLOUT;
250
+ fd.revents = 0;
251
+
252
+ ret = p_poll(&fd, 1, st->parent.timeout);
253
+
254
+ if (ret == 1) {
255
+ ret = p_send(st->s, data, len, 0);
256
+ } else if (ret == 0) {
257
+ git_error_set(GIT_ERROR_NET,
258
+ "could not write to socket: timed out");
259
+ return GIT_TIMEOUT;
260
+ }
261
+ }
262
+
263
+ if (ret < 0) {
264
+ net_set_error("error receiving data from socket");
145
265
  return -1;
146
266
  }
147
267
 
148
- return written;
268
+ return ret;
149
269
  }
150
270
 
151
- static ssize_t socket_read(git_stream *stream, void *data, size_t len)
271
+ static ssize_t socket_read(
272
+ git_stream *stream,
273
+ void *data,
274
+ size_t len)
152
275
  {
153
- ssize_t ret;
154
276
  git_socket_stream *st = (git_socket_stream *) stream;
277
+ struct pollfd fd;
278
+ ssize_t ret;
155
279
 
156
- if ((ret = p_recv(st->s, data, len, 0)) < 0)
157
- net_set_error("error receiving socket data");
280
+ ret = p_recv(st->s, data, len, 0);
281
+
282
+ if (st->parent.timeout && ret < 0 &&
283
+ (errno == EAGAIN || errno != EWOULDBLOCK)) {
284
+ fd.fd = st->s;
285
+ fd.events = POLLIN;
286
+ fd.revents = 0;
287
+
288
+ ret = p_poll(&fd, 1, st->parent.timeout);
289
+
290
+ if (ret == 1) {
291
+ ret = p_recv(st->s, data, len, 0);
292
+ } else if (ret == 0) {
293
+ git_error_set(GIT_ERROR_NET,
294
+ "could not read from socket: timed out");
295
+ return GIT_TIMEOUT;
296
+ }
297
+ }
298
+
299
+ if (ret < 0) {
300
+ net_set_error("error receiving data from socket");
301
+ return -1;
302
+ }
158
303
 
159
304
  return ret;
160
305
  }
@@ -202,6 +347,8 @@ static int default_socket_stream_new(
202
347
  }
203
348
 
204
349
  st->parent.version = GIT_STREAM_VERSION;
350
+ st->parent.timeout = git_socket_stream__timeout;
351
+ st->parent.connect_timeout = git_socket_stream__connect_timeout;
205
352
  st->parent.connect = socket_connect;
206
353
  st->parent.write = socket_write;
207
354
  st->parent.read = socket_read;
@@ -240,3 +387,42 @@ int git_socket_stream_new(
240
387
 
241
388
  return init(out, host, port);
242
389
  }
390
+
391
+ #ifdef GIT_WIN32
392
+
393
+ static void socket_stream_global_shutdown(void)
394
+ {
395
+ WSACleanup();
396
+ }
397
+
398
+ int git_socket_stream_global_init(void)
399
+ {
400
+ WORD winsock_version;
401
+ WSADATA wsa_data;
402
+
403
+ winsock_version = MAKEWORD(2, 2);
404
+
405
+ if (WSAStartup(winsock_version, &wsa_data) != 0) {
406
+ git_error_set(GIT_ERROR_OS, "could not initialize Windows Socket Library");
407
+ return -1;
408
+ }
409
+
410
+ if (LOBYTE(wsa_data.wVersion) != 2 ||
411
+ HIBYTE(wsa_data.wVersion) != 2) {
412
+ git_error_set(GIT_ERROR_SSL, "Windows Socket Library does not support Winsock 2.2");
413
+ return -1;
414
+ }
415
+
416
+ return git_runtime_shutdown_register(socket_stream_global_shutdown);
417
+ }
418
+
419
+ #else
420
+
421
+ #include "stream.h"
422
+
423
+ int git_socket_stream_global_init(void)
424
+ {
425
+ return 0;
426
+ }
427
+
428
+ #endif
@@ -9,7 +9,7 @@
9
9
 
10
10
  #include "common.h"
11
11
 
12
- #include "netops.h"
12
+ #include "stream.h"
13
13
 
14
14
  typedef struct {
15
15
  git_stream parent;
@@ -20,4 +20,6 @@ typedef struct {
20
20
 
21
21
  extern int git_socket_stream_new(git_stream **out, const char *host, const char *port);
22
22
 
23
+ extern int git_socket_stream_global_init(void);
24
+
23
25
  #endif
@@ -44,6 +44,7 @@ typedef struct {
44
44
  git_stream parent;
45
45
  git_stream *io;
46
46
  int owned;
47
+ int error;
47
48
  SSLContextRef ctx;
48
49
  CFDataRef der_data;
49
50
  git_cert_x509 cert_info;
@@ -61,7 +62,10 @@ static int stransport_connect(git_stream *stream)
61
62
  return error;
62
63
 
63
64
  ret = SSLHandshake(st->ctx);
64
- if (ret != errSSLServerAuthCompleted) {
65
+
66
+ if (ret != errSSLServerAuthCompleted && st->error != 0)
67
+ return -1;
68
+ else if (ret != errSSLServerAuthCompleted) {
65
69
  git_error_set(GIT_ERROR_SSL, "unexpected return value from ssl handshake %d", (int)ret);
66
70
  return -1;
67
71
  }
@@ -147,10 +151,20 @@ static int stransport_set_proxy(
147
151
  */
148
152
  static OSStatus write_cb(SSLConnectionRef conn, const void *data, size_t *len)
149
153
  {
150
- git_stream *io = (git_stream *) conn;
154
+ stransport_stream *st = (stransport_stream *)conn;
155
+ git_stream *io = st->io;
156
+ OSStatus ret;
151
157
 
152
- if (git_stream__write_full(io, data, *len, 0) < 0)
153
- return -36; /* "ioErr" from MacErrors.h which is not available on iOS */
158
+ st->error = 0;
159
+
160
+ ret = git_stream__write_full(io, data, *len, 0);
161
+
162
+ if (ret < 0) {
163
+ st->error = ret;
164
+ return (ret == GIT_TIMEOUT) ?
165
+ -9853 /* errSSLNetworkTimeout */:
166
+ -36 /* ioErr */;
167
+ }
154
168
 
155
169
  return noErr;
156
170
  }
@@ -164,8 +178,12 @@ static ssize_t stransport_write(git_stream *stream, const char *data, size_t len
164
178
  GIT_UNUSED(flags);
165
179
 
166
180
  data_len = min(len, SSIZE_MAX);
167
- if ((ret = SSLWrite(st->ctx, data, data_len, &processed)) != noErr)
181
+ if ((ret = SSLWrite(st->ctx, data, data_len, &processed)) != noErr) {
182
+ if (st->error == GIT_TIMEOUT)
183
+ return GIT_TIMEOUT;
184
+
168
185
  return stransport_error(ret);
186
+ }
169
187
 
170
188
  GIT_ASSERT(processed < SSIZE_MAX);
171
189
  return (ssize_t)processed;
@@ -182,18 +200,24 @@ static ssize_t stransport_write(git_stream *stream, const char *data, size_t len
182
200
  */
183
201
  static OSStatus read_cb(SSLConnectionRef conn, void *data, size_t *len)
184
202
  {
185
- git_stream *io = (git_stream *) conn;
203
+ stransport_stream *st = (stransport_stream *)conn;
204
+ git_stream *io = st->io;
186
205
  OSStatus error = noErr;
187
206
  size_t off = 0;
188
207
  ssize_t ret;
189
208
 
209
+ st->error = 0;
210
+
190
211
  do {
191
212
  ret = git_stream_read(io, data + off, *len - off);
213
+
192
214
  if (ret < 0) {
193
- error = -36; /* "ioErr" from MacErrors.h which is not available on iOS */
215
+ st->error = ret;
216
+ error = (ret == GIT_TIMEOUT) ?
217
+ -9853 /* errSSLNetworkTimeout */:
218
+ -36 /* ioErr */;
194
219
  break;
195
- }
196
- if (ret == 0) {
220
+ } else if (ret == 0) {
197
221
  error = errSSLClosedGraceful;
198
222
  break;
199
223
  }
@@ -207,12 +231,16 @@ static OSStatus read_cb(SSLConnectionRef conn, void *data, size_t *len)
207
231
 
208
232
  static ssize_t stransport_read(git_stream *stream, void *data, size_t len)
209
233
  {
210
- stransport_stream *st = (stransport_stream *) stream;
234
+ stransport_stream *st = (stransport_stream *)stream;
211
235
  size_t processed;
212
236
  OSStatus ret;
213
237
 
214
- if ((ret = SSLRead(st->ctx, data, len, &processed)) != noErr)
238
+ if ((ret = SSLRead(st->ctx, data, len, &processed)) != noErr) {
239
+ if (st->error == GIT_TIMEOUT)
240
+ return GIT_TIMEOUT;
241
+
215
242
  return stransport_error(ret);
243
+ }
216
244
 
217
245
  return processed;
218
246
  }
@@ -269,7 +297,7 @@ static int stransport_wrap(
269
297
  }
270
298
 
271
299
  if ((ret = SSLSetIOFuncs(st->ctx, read_cb, write_cb)) != noErr ||
272
- (ret = SSLSetConnection(st->ctx, st->io)) != noErr ||
300
+ (ret = SSLSetConnection(st->ctx, st)) != noErr ||
273
301
  (ret = SSLSetSessionOption(st->ctx, kSSLSessionOptionBreakOnServerAuth, true)) != noErr ||
274
302
  (ret = SSLSetProtocolVersionMin(st->ctx, kTLSProtocol1)) != noErr ||
275
303
  (ret = SSLSetProtocolVersionMax(st->ctx, kTLSProtocol12)) != noErr ||
@@ -13,6 +13,7 @@
13
13
  #include "streams/mbedtls.h"
14
14
  #include "streams/openssl.h"
15
15
  #include "streams/stransport.h"
16
+ #include "streams/schannel.h"
16
17
 
17
18
  int git_tls_stream_new(git_stream **out, const char *host, const char *port)
18
19
  {
@@ -33,6 +34,8 @@ int git_tls_stream_new(git_stream **out, const char *host, const char *port)
33
34
  init = git_openssl_stream_new;
34
35
  #elif defined(GIT_MBEDTLS)
35
36
  init = git_mbedtls_stream_new;
37
+ #elif defined(GIT_SCHANNEL)
38
+ init = git_schannel_stream_new;
36
39
  #endif
37
40
  } else {
38
41
  return error;
@@ -63,6 +66,8 @@ int git_tls_stream_wrap(git_stream **out, git_stream *in, const char *host)
63
66
  wrap = git_openssl_stream_wrap;
64
67
  #elif defined(GIT_MBEDTLS)
65
68
  wrap = git_mbedtls_stream_wrap;
69
+ #elif defined(GIT_SCHANNEL)
70
+ wrap = git_schannel_stream_wrap;
66
71
  #endif
67
72
  }
68
73
 
@@ -69,9 +69,9 @@
69
69
  * - `repo` is the parent repository that contains this submodule.
70
70
  * - `flags` after for internal use, tracking where this submodule has been
71
71
  * found (head, index, config, workdir) and known status info, etc.
72
- * - `head_oid` is the SHA1 for the submodule path in the repo HEAD.
73
- * - `index_oid` is the SHA1 for the submodule recorded in the index.
74
- * - `wd_oid` is the SHA1 for the HEAD of the checked out submodule.
72
+ * - `head_oid` is the oid for the submodule path in the repo HEAD.
73
+ * - `index_oid` is the oid for the submodule recorded in the index.
74
+ * - `wd_oid` is the oid for the HEAD of the checked out submodule.
75
75
  *
76
76
  * If the submodule has been added to .gitmodules but not yet git added,
77
77
  * then the `index_oid` will be zero but still marked valid. If the
@@ -75,10 +75,23 @@ git_threadstate *git_threadstate_get(void)
75
75
  if ((threadstate = git_tlsdata_get(tls_key)) != NULL)
76
76
  return threadstate;
77
77
 
78
- if ((threadstate = git__calloc(1, sizeof(git_threadstate))) == NULL ||
79
- git_str_init(&threadstate->error_buf, 0) < 0)
78
+ /*
79
+ * Avoid git__malloc here, since if it fails, it sets an error
80
+ * message, which requires thread state, which would allocate
81
+ * here, which would fail, which would set an error message...
82
+ */
83
+
84
+ if ((threadstate = git__allocator.gmalloc(sizeof(git_threadstate),
85
+ __FILE__, __LINE__)) == NULL)
80
86
  return NULL;
81
87
 
88
+ memset(threadstate, 0, sizeof(git_threadstate));
89
+
90
+ if (git_str_init(&threadstate->error_buf, 0) < 0) {
91
+ git__allocator.gfree(threadstate);
92
+ return NULL;
93
+ }
94
+
82
95
  git_tlsdata_set(tls_key, threadstate);
83
96
  return threadstate;
84
97
  }
@@ -13,12 +13,10 @@ typedef struct {
13
13
  git_error *last_error;
14
14
  git_error error_t;
15
15
  git_str error_buf;
16
- char oid_fmt[GIT_OID_SHA1_HEXSIZE+1];
16
+ char oid_fmt[GIT_OID_MAX_HEXSIZE+1];
17
17
  } git_threadstate;
18
18
 
19
19
  extern int git_threadstate_global_init(void);
20
20
  extern git_threadstate *git_threadstate_get(void);
21
21
 
22
- #define GIT_THREADSTATE (git_threadstate_get())
23
-
24
22
  #endif
@@ -9,8 +9,7 @@
9
9
  #define INCLUDE_transports_auth_h__
10
10
 
11
11
  #include "common.h"
12
-
13
- #include "netops.h"
12
+ #include "net.h"
14
13
 
15
14
  typedef enum {
16
15
  GIT_HTTP_AUTH_BASIC = 1,