mirror of
https://github.com/git-for-windows/git.git
synced 2026-04-27 18:11:59 -05:00
http: support lazy-loading libcurl also on Windows
This implements the Windows-specific support code, because everything is slightly different on Windows, even loading shared libraries. Note: I specifically do _not_ use the code from `compat/win32/lazyload.h` here because that code is optimized for loading individual functions from various system DLLs, while we specifically want to load _many_ functions from _one_ DLL here, and distinctly not a system DLL (we expect libcurl to be located outside `C:\Windows\system32`, something `INIT_PROC_ADDR` refuses to work with). Also, the `curl_easy_getinfo()`/`curl_easy_setopt()` functions are declared as vararg functions, which `lazyload.h` cannot handle. Finally, we are about to optionally override the exact file name that is to be loaded, which is a goal contrary to `lazyload.h`'s design. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This commit is contained in:
4
Makefile
4
Makefile
@@ -1627,7 +1627,11 @@ else
|
|||||||
# The `CURL_STATICLIB` constant must be defined to avoid seeing the functions
|
# The `CURL_STATICLIB` constant must be defined to avoid seeing the functions
|
||||||
# declared as DLL imports
|
# declared as DLL imports
|
||||||
CURL_CFLAGS = -DCURL_STATICLIB
|
CURL_CFLAGS = -DCURL_STATICLIB
|
||||||
|
ifneq ($(uname_S),MINGW)
|
||||||
|
ifneq ($(uname_S),Windows)
|
||||||
CURL_LIBCURL = -ldl
|
CURL_LIBCURL = -ldl
|
||||||
|
endif
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
ifndef CURL_LDFLAGS
|
ifndef CURL_LDFLAGS
|
||||||
CURL_LDFLAGS = $(eval CURL_LDFLAGS := $$(shell $$(CURL_CONFIG) --libs))$(CURL_LDFLAGS)
|
CURL_LDFLAGS = $(eval CURL_LDFLAGS := $$(shell $$(CURL_CONFIG) --libs))$(CURL_LDFLAGS)
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#include "../git-compat-util.h"
|
#include "../git-compat-util.h"
|
||||||
#include "../git-curl-compat.h"
|
#include "../git-curl-compat.h"
|
||||||
|
#ifndef WIN32
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The ABI version of libcurl is encoded in its shared libraries' file names.
|
* The ABI version of libcurl is encoded in its shared libraries' file names.
|
||||||
@@ -11,6 +13,7 @@
|
|||||||
|
|
||||||
typedef void (*func_t)(void);
|
typedef void (*func_t)(void);
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#define LIBCURL_FILE_NAME(base) base "." LIBCURL_ABI_VERSION ".dylib"
|
#define LIBCURL_FILE_NAME(base) base "." LIBCURL_ABI_VERSION ".dylib"
|
||||||
#else
|
#else
|
||||||
@@ -35,6 +38,55 @@ static func_t load_function(void *handle, const char *name)
|
|||||||
*(void **)&f = dlsym(handle, name);
|
*(void **)&f = dlsym(handle, name);
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
#define LIBCURL_FILE_NAME(base) base "-" LIBCURL_ABI_VERSION ".dll"
|
||||||
|
|
||||||
|
static void *load_library(const char *name)
|
||||||
|
{
|
||||||
|
size_t name_size = strlen(name) + 1;
|
||||||
|
const char *path = getenv("PATH");
|
||||||
|
char dll_path[MAX_PATH];
|
||||||
|
|
||||||
|
while (path && *path) {
|
||||||
|
const char *sep = strchrnul(path, ';');
|
||||||
|
size_t len = sep - path;
|
||||||
|
|
||||||
|
if (len && len + name_size < sizeof(dll_path)) {
|
||||||
|
memcpy(dll_path, path, len);
|
||||||
|
dll_path[len] = '/';
|
||||||
|
memcpy(dll_path + len + 1, name, name_size);
|
||||||
|
|
||||||
|
if (!access(dll_path, R_OK)) {
|
||||||
|
wchar_t wpath[MAX_PATH];
|
||||||
|
int wlen = MultiByteToWideChar(CP_UTF8, 0, dll_path, -1, wpath, ARRAY_SIZE(wpath));
|
||||||
|
void *res = wlen ? (void *)LoadLibraryExW(wpath, NULL, 0) : NULL;
|
||||||
|
if (!res) {
|
||||||
|
DWORD err = GetLastError();
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
if (!FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
|
FORMAT_MESSAGE_ARGUMENT_ARRAY |
|
||||||
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
NULL, err, LANG_NEUTRAL,
|
||||||
|
buf, sizeof(buf) - 1, NULL))
|
||||||
|
xsnprintf(buf, sizeof(buf), "last error: %ld", err);
|
||||||
|
error("LoadLibraryExW() failed with: %s", buf);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
path = *sep ? sep + 1 : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static func_t load_function(void *handle, const char *name)
|
||||||
|
{
|
||||||
|
return (func_t)GetProcAddress((HANDLE)handle, name);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef char *(*curl_easy_escape_type)(CURL *handle, const char *string, int length);
|
typedef char *(*curl_easy_escape_type)(CURL *handle, const char *string, int length);
|
||||||
static curl_easy_escape_type curl_easy_escape_func;
|
static curl_easy_escape_type curl_easy_escape_func;
|
||||||
|
|||||||
Reference in New Issue
Block a user