summaryrefslogtreecommitdiff
path: root/compat
diff options
context:
space:
mode:
Diffstat (limited to 'compat')
-rw-r--r--compat/.gitattributes1
-rw-r--r--compat/mingw.c8
-rw-r--r--compat/simple-ipc/ipc-unix-socket.c22
-rw-r--r--compat/terminal.c75
-rw-r--r--compat/terminal.h3
-rw-r--r--compat/unsetenv.c4
-rw-r--r--compat/win32/lazyload.h6
-rw-r--r--compat/win32/trace2_win32_process_info.c4
-rw-r--r--compat/winansi.c5
-rw-r--r--compat/zlib-uncompress2.c95
10 files changed, 198 insertions, 25 deletions
diff --git a/compat/.gitattributes b/compat/.gitattributes
new file mode 100644
index 0000000000..40dbfb170d
--- /dev/null
+++ b/compat/.gitattributes
@@ -0,0 +1 @@
+/zlib-uncompress2.c whitespace=-indent-with-non-tab,-trailing-space
diff --git a/compat/mingw.c b/compat/mingw.c
index 9e0cd1e097..640dcb11de 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -8,6 +8,8 @@
#include "win32/lazyload.h"
#include "../config.h"
#include "dir.h"
+#define SECURITY_WIN32
+#include <sspi.h>
#define HCAST(type, handle) ((type)(intptr_t)handle)
@@ -1008,7 +1010,7 @@ size_t mingw_strftime(char *s, size_t max,
/* a pointer to the original strftime in case we can't find the UCRT version */
static size_t (*fallback)(char *, size_t, const char *, const struct tm *) = strftime;
size_t ret;
- DECLARE_PROC_ADDR(ucrtbase.dll, size_t, strftime, char *, size_t,
+ DECLARE_PROC_ADDR(ucrtbase.dll, size_t, __cdecl, strftime, char *, size_t,
const char *, const struct tm *);
if (INIT_PROC_ADDR(strftime))
@@ -1083,6 +1085,7 @@ int pipe(int filedes[2])
return 0;
}
+#ifndef __MINGW64__
struct tm *gmtime_r(const time_t *timep, struct tm *result)
{
if (gmtime_s(result, timep) == 0)
@@ -1096,6 +1099,7 @@ struct tm *localtime_r(const time_t *timep, struct tm *result)
return result;
return NULL;
}
+#endif
char *mingw_getcwd(char *pointer, int len)
{
@@ -2183,7 +2187,7 @@ enum EXTENDED_NAME_FORMAT {
static char *get_extended_user_info(enum EXTENDED_NAME_FORMAT type)
{
- DECLARE_PROC_ADDR(secur32.dll, BOOL, GetUserNameExW,
+ DECLARE_PROC_ADDR(secur32.dll, BOOL, SEC_ENTRY, GetUserNameExW,
enum EXTENDED_NAME_FORMAT, LPCWSTR, PULONG);
static wchar_t wbuffer[1024];
DWORD len;
diff --git a/compat/simple-ipc/ipc-unix-socket.c b/compat/simple-ipc/ipc-unix-socket.c
index 4e28857a0a..28a79289d4 100644
--- a/compat/simple-ipc/ipc-unix-socket.c
+++ b/compat/simple-ipc/ipc-unix-socket.c
@@ -35,6 +35,28 @@ enum ipc_active_state ipc_get_active_state(const char *path)
}
}
+#ifdef __CYGWIN__
+ /*
+ * Cygwin emulates Unix sockets by writing special-crafted files whose
+ * `system` bit is set.
+ *
+ * If we are too fast, Cygwin might still be in the process of marking
+ * the underlying file as a system file. Until then, we will not see a
+ * Unix socket here, but a plain file instead. Just in case that this
+ * is happening, wait a little and try again.
+ */
+ {
+ static const int delay[] = { 1, 10, 20, 40, -1 };
+ int i;
+
+ for (i = 0; S_ISREG(st.st_mode) && delay[i] > 0; i++) {
+ sleep_millisec(delay[i]);
+ if (lstat(path, &st) == -1)
+ return IPC_STATE__INVALID_PATH;
+ }
+ }
+#endif
+
/* also complain if a plain file is in the way */
if ((st.st_mode & S_IFMT) != S_IFSOCK)
return IPC_STATE__INVALID_PATH;
diff --git a/compat/terminal.c b/compat/terminal.c
index 43b73ddc75..5b903e7c7e 100644
--- a/compat/terminal.c
+++ b/compat/terminal.c
@@ -8,8 +8,6 @@
#if defined(HAVE_DEV_TTY) || defined(GIT_WINDOWS_NATIVE)
-static void restore_term(void);
-
static void restore_term_on_signal(int sig)
{
restore_term();
@@ -25,7 +23,7 @@ static void restore_term_on_signal(int sig)
static int term_fd = -1;
static struct termios old_term;
-static void restore_term(void)
+void restore_term(void)
{
if (term_fd < 0)
return;
@@ -35,15 +33,22 @@ static void restore_term(void)
term_fd = -1;
}
+int save_term(int full_duplex)
+{
+ if (term_fd < 0)
+ term_fd = open("/dev/tty", O_RDWR);
+
+ return (term_fd < 0) ? -1 : tcgetattr(term_fd, &old_term);
+}
+
static int disable_bits(tcflag_t bits)
{
struct termios t;
- term_fd = open("/dev/tty", O_RDWR);
- if (tcgetattr(term_fd, &t) < 0)
+ if (save_term(0) < 0)
goto error;
- old_term = t;
+ t = old_term;
sigchain_push_common(restore_term_on_signal);
t.c_lflag &= ~bits;
@@ -75,9 +80,10 @@ static int enable_non_canonical(void)
static int use_stty = 1;
static struct string_list stty_restore = STRING_LIST_INIT_DUP;
static HANDLE hconin = INVALID_HANDLE_VALUE;
-static DWORD cmode;
+static HANDLE hconout = INVALID_HANDLE_VALUE;
+static DWORD cmode_in, cmode_out;
-static void restore_term(void)
+void restore_term(void)
{
if (use_stty) {
int i;
@@ -97,9 +103,42 @@ static void restore_term(void)
if (hconin == INVALID_HANDLE_VALUE)
return;
- SetConsoleMode(hconin, cmode);
+ SetConsoleMode(hconin, cmode_in);
+ CloseHandle(hconin);
+ if (cmode_out) {
+ assert(hconout != INVALID_HANDLE_VALUE);
+ SetConsoleMode(hconout, cmode_out);
+ CloseHandle(hconout);
+ }
+
+ hconin = hconout = INVALID_HANDLE_VALUE;
+}
+
+int save_term(int full_duplex)
+{
+ hconin = CreateFileA("CONIN$", GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ, NULL, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hconin == INVALID_HANDLE_VALUE)
+ return -1;
+
+ if (full_duplex) {
+ hconout = CreateFileA("CONOUT$", GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hconout == INVALID_HANDLE_VALUE)
+ goto error;
+
+ GetConsoleMode(hconout, &cmode_out);
+ }
+
+ GetConsoleMode(hconin, &cmode_in);
+ use_stty = 0;
+ return 0;
+error:
CloseHandle(hconin);
hconin = INVALID_HANDLE_VALUE;
+ return -1;
}
static int disable_bits(DWORD bits)
@@ -135,15 +174,11 @@ static int disable_bits(DWORD bits)
use_stty = 0;
}
- hconin = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ, NULL, OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL, NULL);
- if (hconin == INVALID_HANDLE_VALUE)
+ if (save_term(0) < 0)
return -1;
- GetConsoleMode(hconin, &cmode);
sigchain_push_common(restore_term_on_signal);
- if (!SetConsoleMode(hconin, cmode & ~bits)) {
+ if (!SetConsoleMode(hconin, cmode_in & ~bits)) {
CloseHandle(hconin);
hconin = INVALID_HANDLE_VALUE;
return -1;
@@ -361,6 +396,16 @@ int read_key_without_echo(struct strbuf *buf)
#else
+int save_term(int full_duplex)
+{
+ /* full_duplex == 1, but no support available */
+ return -full_duplex;
+}
+
+void restore_term(void)
+{
+}
+
char *git_terminal_prompt(const char *prompt, int echo)
{
return getpass(prompt);
diff --git a/compat/terminal.h b/compat/terminal.h
index a9d52b8464..e1770c575b 100644
--- a/compat/terminal.h
+++ b/compat/terminal.h
@@ -1,6 +1,9 @@
#ifndef COMPAT_TERMINAL_H
#define COMPAT_TERMINAL_H
+int save_term(int full_duplex);
+void restore_term(void);
+
char *git_terminal_prompt(const char *prompt, int echo);
/* Read a single keystroke, without echoing it to the terminal */
diff --git a/compat/unsetenv.c b/compat/unsetenv.c
index bf5fd7063b..b9d34af613 100644
--- a/compat/unsetenv.c
+++ b/compat/unsetenv.c
@@ -1,6 +1,6 @@
#include "../git-compat-util.h"
-void gitunsetenv (const char *name)
+int gitunsetenv(const char *name)
{
#if !defined(__MINGW32__)
extern char **environ;
@@ -24,4 +24,6 @@ void gitunsetenv (const char *name)
++dst;
}
environ[dst] = NULL;
+
+ return 0;
}
diff --git a/compat/win32/lazyload.h b/compat/win32/lazyload.h
index 2b3637135f..f2bb96c89c 100644
--- a/compat/win32/lazyload.h
+++ b/compat/win32/lazyload.h
@@ -4,7 +4,7 @@
/*
* A pair of macros to simplify loading of DLL functions. Example:
*
- * DECLARE_PROC_ADDR(kernel32.dll, BOOL, CreateHardLinkW,
+ * DECLARE_PROC_ADDR(kernel32.dll, BOOL, WINAPI, CreateHardLinkW,
* LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);
*
* if (!INIT_PROC_ADDR(CreateHardLinkW))
@@ -25,10 +25,10 @@ struct proc_addr {
};
/* Declares a function to be loaded dynamically from a DLL. */
-#define DECLARE_PROC_ADDR(dll, rettype, function, ...) \
+#define DECLARE_PROC_ADDR(dll, rettype, convention, function, ...) \
static struct proc_addr proc_addr_##function = \
{ #dll, #function, NULL, 0 }; \
- typedef rettype (WINAPI *proc_type_##function)(__VA_ARGS__); \
+ typedef rettype (convention *proc_type_##function)(__VA_ARGS__); \
static proc_type_##function function
/*
diff --git a/compat/win32/trace2_win32_process_info.c b/compat/win32/trace2_win32_process_info.c
index 8ccbd1c2c6..a53fd92434 100644
--- a/compat/win32/trace2_win32_process_info.c
+++ b/compat/win32/trace2_win32_process_info.c
@@ -143,8 +143,8 @@ static void get_is_being_debugged(void)
*/
static void get_peak_memory_info(void)
{
- DECLARE_PROC_ADDR(psapi.dll, BOOL, GetProcessMemoryInfo, HANDLE,
- PPROCESS_MEMORY_COUNTERS, DWORD);
+ DECLARE_PROC_ADDR(psapi.dll, BOOL, WINAPI, GetProcessMemoryInfo,
+ HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD);
if (INIT_PROC_ADDR(GetProcessMemoryInfo)) {
PROCESS_MEMORY_COUNTERS pmc;
diff --git a/compat/winansi.c b/compat/winansi.c
index c27b20a79d..4fceecf14c 100644
--- a/compat/winansi.c
+++ b/compat/winansi.c
@@ -45,8 +45,9 @@ typedef struct _CONSOLE_FONT_INFOEX {
static void warn_if_raster_font(void)
{
DWORD fontFamily = 0;
- DECLARE_PROC_ADDR(kernel32.dll, BOOL, GetCurrentConsoleFontEx,
- HANDLE, BOOL, PCONSOLE_FONT_INFOEX);
+ DECLARE_PROC_ADDR(kernel32.dll, BOOL, WINAPI,
+ GetCurrentConsoleFontEx, HANDLE, BOOL,
+ PCONSOLE_FONT_INFOEX);
/* don't bother if output was ascii only */
if (!non_ascii_used)
diff --git a/compat/zlib-uncompress2.c b/compat/zlib-uncompress2.c
new file mode 100644
index 0000000000..722610b971
--- /dev/null
+++ b/compat/zlib-uncompress2.c
@@ -0,0 +1,95 @@
+/* taken from zlib's uncompr.c
+
+ commit cacf7f1d4e3d44d871b605da3b647f07d718623f
+ Author: Mark Adler <madler@alumni.caltech.edu>
+ Date: Sun Jan 15 09:18:46 2017 -0800
+
+ zlib 1.2.11
+
+*/
+
+#include "../reftable/system.h"
+#define z_const
+
+/*
+ * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include <zlib.h>
+
+/* clang-format off */
+
+/* ===========================================================================
+ Decompresses the source buffer into the destination buffer. *sourceLen is
+ the byte length of the source buffer. Upon entry, *destLen is the total size
+ of the destination buffer, which must be large enough to hold the entire
+ uncompressed data. (The size of the uncompressed data must have been saved
+ previously by the compressor and transmitted to the decompressor by some
+ mechanism outside the scope of this compression library.) Upon exit,
+ *destLen is the size of the decompressed data and *sourceLen is the number
+ of source bytes consumed. Upon return, source + *sourceLen points to the
+ first unused input byte.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer, or
+ Z_DATA_ERROR if the input data was corrupted, including if the input data is
+ an incomplete zlib stream.
+*/
+int ZEXPORT uncompress2 (
+ Bytef *dest,
+ uLongf *destLen,
+ const Bytef *source,
+ uLong *sourceLen) {
+ z_stream stream;
+ int err;
+ const uInt max = (uInt)-1;
+ uLong len, left;
+ Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */
+
+ len = *sourceLen;
+ if (*destLen) {
+ left = *destLen;
+ *destLen = 0;
+ }
+ else {
+ left = 1;
+ dest = buf;
+ }
+
+ stream.next_in = (z_const Bytef *)source;
+ stream.avail_in = 0;
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+ stream.opaque = (voidpf)0;
+
+ err = inflateInit(&stream);
+ if (err != Z_OK) return err;
+
+ stream.next_out = dest;
+ stream.avail_out = 0;
+
+ do {
+ if (stream.avail_out == 0) {
+ stream.avail_out = left > (uLong)max ? max : (uInt)left;
+ left -= stream.avail_out;
+ }
+ if (stream.avail_in == 0) {
+ stream.avail_in = len > (uLong)max ? max : (uInt)len;
+ len -= stream.avail_in;
+ }
+ err = inflate(&stream, Z_NO_FLUSH);
+ } while (err == Z_OK);
+
+ *sourceLen -= len + stream.avail_in;
+ if (dest != buf)
+ *destLen = stream.total_out;
+ else if (stream.total_out && err == Z_BUF_ERROR)
+ left = 1;
+
+ inflateEnd(&stream);
+ return err == Z_STREAM_END ? Z_OK :
+ err == Z_NEED_DICT ? Z_DATA_ERROR :
+ err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR :
+ err;
+}