#include "../git-compat-util.h"
#include "win32.h"
#include <conio.h>
#include <wchar.h>
#include "../strbuf.h"
#include "../run-command.h"
#include "../cache.h"
#include "win32/lazyload.h"
#include "../config.h"
#include "dir.h"

#define HCAST(type, handle) ((type)(intptr_t)handle)

static const int delay[] = { 0, 1, 10, 20, 40 };

int err_win_to_posix(DWORD winerr)
{
	int error = ENOSYS;
	switch(winerr) {
	case ERROR_ACCESS_DENIED: error = EACCES; break;
	case ERROR_ACCOUNT_DISABLED: error = EACCES; break;
	case ERROR_ACCOUNT_RESTRICTION: error = EACCES; break;
	case ERROR_ALREADY_ASSIGNED: error = EBUSY; break;
	case ERROR_ALREADY_EXISTS: error = EEXIST; break;
	case ERROR_ARITHMETIC_OVERFLOW: error = ERANGE; break;
	case ERROR_BAD_COMMAND: error = EIO; break;
	case ERROR_BAD_DEVICE: error = ENODEV; break;
	case ERROR_BAD_DRIVER_LEVEL: error = ENXIO; break;
	case ERROR_BAD_EXE_FORMAT: error = ENOEXEC; break;
	case ERROR_BAD_FORMAT: error = ENOEXEC; break;
	case ERROR_BAD_LENGTH: error = EINVAL; break;
	case ERROR_BAD_PATHNAME: error = ENOENT; break;
	case ERROR_BAD_PIPE: error = EPIPE; break;
	case ERROR_BAD_UNIT: error = ENODEV; break;
	case ERROR_BAD_USERNAME: error = EINVAL; break;
	case ERROR_BROKEN_PIPE: error = EPIPE; break;
	case ERROR_BUFFER_OVERFLOW: error = ENAMETOOLONG; break;
	case ERROR_BUSY: error = EBUSY; break;
	case ERROR_BUSY_DRIVE: error = EBUSY; break;
	case ERROR_CALL_NOT_IMPLEMENTED: error = ENOSYS; break;
	case ERROR_CANNOT_MAKE: error = EACCES; break;
	case ERROR_CANTOPEN: error = EIO; break;
	case ERROR_CANTREAD: error = EIO; break;
	case ERROR_CANTWRITE: error = EIO; break;
	case ERROR_CRC: error = EIO; break;
	case ERROR_CURRENT_DIRECTORY: error = EACCES; break;
	case ERROR_DEVICE_IN_USE: error = EBUSY; break;
	case ERROR_DEV_NOT_EXIST: error = ENODEV; break;
	case ERROR_DIRECTORY: error = EINVAL; break;
	case ERROR_DIR_NOT_EMPTY: error = ENOTEMPTY; break;
	case ERROR_DISK_CHANGE: error = EIO; break;
	case ERROR_DISK_FULL: error = ENOSPC; break;
	case ERROR_DRIVE_LOCKED: error = EBUSY; break;
	case ERROR_ENVVAR_NOT_FOUND: error = EINVAL; break;
	case ERROR_EXE_MARKED_INVALID: error = ENOEXEC; break;
	case ERROR_FILENAME_EXCED_RANGE: error = ENAMETOOLONG; break;
	case ERROR_FILE_EXISTS: error = EEXIST; break;
	case ERROR_FILE_INVALID: error = ENODEV; break;
	case ERROR_FILE_NOT_FOUND: error = ENOENT; break;
	case ERROR_GEN_FAILURE: error = EIO; break;
	case ERROR_HANDLE_DISK_FULL: error = ENOSPC; break;
	case ERROR_INSUFFICIENT_BUFFER: error = ENOMEM; break;
	case ERROR_INVALID_ACCESS: error = EACCES; break;
	case ERROR_INVALID_ADDRESS: error = EFAULT; break;
	case ERROR_INVALID_BLOCK: error = EFAULT; break;
	case ERROR_INVALID_DATA: error = EINVAL; break;
	case ERROR_INVALID_DRIVE: error = ENODEV; break;
	case ERROR_INVALID_EXE_SIGNATURE: error = ENOEXEC; break;
	case ERROR_INVALID_FLAGS: error = EINVAL; break;
	case ERROR_INVALID_FUNCTION: error = ENOSYS; break;
	case ERROR_INVALID_HANDLE: error = EBADF; break;
	case ERROR_INVALID_LOGON_HOURS: error = EACCES; break;
	case ERROR_INVALID_NAME: error = EINVAL; break;
	case ERROR_INVALID_OWNER: error = EINVAL; break;
	case ERROR_INVALID_PARAMETER: error = EINVAL; break;
	case ERROR_INVALID_PASSWORD: error = EPERM; break;
	case ERROR_INVALID_PRIMARY_GROUP: error = EINVAL; break;
	case ERROR_INVALID_SIGNAL_NUMBER: error = EINVAL; break;
	case ERROR_INVALID_TARGET_HANDLE: error = EIO; break;
	case ERROR_INVALID_WORKSTATION: error = EACCES; break;
	case ERROR_IO_DEVICE: error = EIO; break;
	case ERROR_IO_INCOMPLETE: error = EINTR; break;
	case ERROR_LOCKED: error = EBUSY; break;
	case ERROR_LOCK_VIOLATION: error = EACCES; break;
	case ERROR_LOGON_FAILURE: error = EACCES; break;
	case ERROR_MAPPED_ALIGNMENT: error = EINVAL; break;
	case ERROR_META_EXPANSION_TOO_LONG: error = E2BIG; break;
	case ERROR_MORE_DATA: error = EPIPE; break;
	case ERROR_NEGATIVE_SEEK: error = ESPIPE; break;
	case ERROR_NOACCESS: error = EFAULT; break;
	case ERROR_NONE_MAPPED: error = EINVAL; break;
	case ERROR_NOT_ENOUGH_MEMORY: error = ENOMEM; break;
	case ERROR_NOT_READY: error = EAGAIN; break;
	case ERROR_NOT_SAME_DEVICE: error = EXDEV; break;
	case ERROR_NO_DATA: error = EPIPE; break;
	case ERROR_NO_MORE_SEARCH_HANDLES: error = EIO; break;
	case ERROR_NO_PROC_SLOTS: error = EAGAIN; break;
	case ERROR_NO_SUCH_PRIVILEGE: error = EACCES; break;
	case ERROR_OPEN_FAILED: error = EIO; break;
	case ERROR_OPEN_FILES: error = EBUSY; break;
	case ERROR_OPERATION_ABORTED: error = EINTR; break;
	case ERROR_OUTOFMEMORY: error = ENOMEM; break;
	case ERROR_PASSWORD_EXPIRED: error = EACCES; break;
	case ERROR_PATH_BUSY: error = EBUSY; break;
	case ERROR_PATH_NOT_FOUND: error = ENOENT; break;
	case ERROR_PIPE_BUSY: error = EBUSY; break;
	case ERROR_PIPE_CONNECTED: error = EPIPE; break;
	case ERROR_PIPE_LISTENING: error = EPIPE; break;
	case ERROR_PIPE_NOT_CONNECTED: error = EPIPE; break;
	case ERROR_PRIVILEGE_NOT_HELD: error = EACCES; break;
	case ERROR_READ_FAULT: error = EIO; break;
	case ERROR_SEEK: error = EIO; break;
	case ERROR_SEEK_ON_DEVICE: error = ESPIPE; break;
	case ERROR_SHARING_BUFFER_EXCEEDED: error = ENFILE; break;
	case ERROR_SHARING_VIOLATION: error = EACCES; break;
	case ERROR_STACK_OVERFLOW: error = ENOMEM; break;
	case ERROR_SUCCESS: BUG("err_win_to_posix() called without an error!");
	case ERROR_SWAPERROR: error = ENOENT; break;
	case ERROR_TOO_MANY_MODULES: error = EMFILE; break;
	case ERROR_TOO_MANY_OPEN_FILES: error = EMFILE; break;
	case ERROR_UNRECOGNIZED_MEDIA: error = ENXIO; break;
	case ERROR_UNRECOGNIZED_VOLUME: error = ENODEV; break;
	case ERROR_WAIT_NO_CHILDREN: error = ECHILD; break;
	case ERROR_WRITE_FAULT: error = EIO; break;
	case ERROR_WRITE_PROTECT: error = EROFS; break;
	}
	return error;
}

static inline int is_file_in_use_error(DWORD errcode)
{
	switch (errcode) {
	case ERROR_SHARING_VIOLATION:
	case ERROR_ACCESS_DENIED:
		return 1;
	}

	return 0;
}

static int read_yes_no_answer(void)
{
	char answer[1024];

	if (fgets(answer, sizeof(answer), stdin)) {
		size_t answer_len = strlen(answer);
		int got_full_line = 0, c;

		/* remove the newline */
		if (answer_len >= 2 && answer[answer_len-2] == '\r') {
			answer[answer_len-2] = '\0';
			got_full_line = 1;
		} else if (answer_len >= 1 && answer[answer_len-1] == '\n') {
			answer[answer_len-1] = '\0';
			got_full_line = 1;
		}
		/* flush the buffer in case we did not get the full line */
		if (!got_full_line)
			while ((c = getchar()) != EOF && c != '\n')
				;
	} else
		/* we could not read, return the
		 * default answer which is no */
		return 0;

	if (tolower(answer[0]) == 'y' && !answer[1])
		return 1;
	if (!strncasecmp(answer, "yes", sizeof(answer)))
		return 1;
	if (tolower(answer[0]) == 'n' && !answer[1])
		return 0;
	if (!strncasecmp(answer, "no", sizeof(answer)))
		return 0;

	/* did not find an answer we understand */
	return -1;
}

static int ask_yes_no_if_possible(const char *format, ...)
{
	char question[4096];
	const char *retry_hook[] = { NULL, NULL, NULL };
	va_list args;

	va_start(args, format);
	vsnprintf(question, sizeof(question), format, args);
	va_end(args);

	if ((retry_hook[0] = mingw_getenv("GIT_ASK_YESNO"))) {
		retry_hook[1] = question;
		return !run_command_v_opt(retry_hook, 0);
	}

	if (!isatty(_fileno(stdin)) || !isatty(_fileno(stderr)))
		return 0;

	while (1) {
		int answer;
		fprintf(stderr, "%s (y/n) ", question);

		if ((answer = read_yes_no_answer()) >= 0)
			return answer;

		fprintf(stderr, "Sorry, I did not understand your answer. "
				"Please type 'y' or 'n'\n");
	}
}

/* Windows only */
enum hide_dotfiles_type {
	HIDE_DOTFILES_FALSE = 0,
	HIDE_DOTFILES_TRUE,
	HIDE_DOTFILES_DOTGITONLY
};

static int core_restrict_inherited_handles = -1;
static enum hide_dotfiles_type hide_dotfiles = HIDE_DOTFILES_DOTGITONLY;
static char *unset_environment_variables;

int mingw_core_config(const char *var, const char *value, void *cb)
{
	if (!strcmp(var, "core.hidedotfiles")) {
		if (value && !strcasecmp(value, "dotgitonly"))
			hide_dotfiles = HIDE_DOTFILES_DOTGITONLY;
		else
			hide_dotfiles = git_config_bool(var, value);
		return 0;
	}

	if (!strcmp(var, "core.unsetenvvars")) {
		free(unset_environment_variables);
		unset_environment_variables = xstrdup(value);
		return 0;
	}

	if (!strcmp(var, "core.restrictinheritedhandles")) {
		if (value && !strcasecmp(value, "auto"))
			core_restrict_inherited_handles = -1;
		else
			core_restrict_inherited_handles =
				git_config_bool(var, value);
		return 0;
	}

	return 0;
}

/* Normalizes NT paths as returned by some low-level APIs. */
static wchar_t *normalize_ntpath(wchar_t *wbuf)
{
	int i;
	/* fix absolute path prefixes */
	if (wbuf[0] == '\\') {
		/* strip NT namespace prefixes */
		if (!wcsncmp(wbuf, L"\\??\\", 4) ||
		    !wcsncmp(wbuf, L"\\\\?\\", 4))
			wbuf += 4;
		else if (!wcsnicmp(wbuf, L"\\DosDevices\\", 12))
			wbuf += 12;
		/* replace remaining '...UNC\' with '\\' */
		if (!wcsnicmp(wbuf, L"UNC\\", 4)) {
			wbuf += 2;
			*wbuf = '\\';
		}
	}
	/* convert backslashes to slashes */
	for (i = 0; wbuf[i]; i++)
		if (wbuf[i] == '\\')
			wbuf[i] = '/';
	return wbuf;
}

int mingw_unlink(const char *pathname)
{
	int ret, tries = 0;
	wchar_t wpathname[MAX_PATH];
	if (xutftowcs_path(wpathname, pathname) < 0)
		return -1;

	/* read-only files cannot be removed */
	_wchmod(wpathname, 0666);
	while ((ret = _wunlink(wpathname)) == -1 && tries < ARRAY_SIZE(delay)) {
		if (!is_file_in_use_error(GetLastError()))
			break;
		/*
		 * We assume that some other process had the source or
		 * destination file open at the wrong moment and retry.
		 * In order to give the other process a higher chance to
		 * complete its operation, we give up our time slice now.
		 * If we have to retry again, we do sleep a bit.
		 */
		Sleep(delay[tries]);
		tries++;
	}
	while (ret == -1 && is_file_in_use_error(GetLastError()) &&
	       ask_yes_no_if_possible("Unlink of file '%s' failed. "
			"Should I try again?", pathname))
	       ret = _wunlink(wpathname);
	return ret;
}

static int is_dir_empty(const wchar_t *wpath)
{
	WIN32_FIND_DATAW findbuf;
	HANDLE handle;
	wchar_t wbuf[MAX_PATH + 2];
	wcscpy(wbuf, wpath);
	wcscat(wbuf, L"\\*");
	handle = FindFirstFileW(wbuf, &findbuf);
	if (handle == INVALID_HANDLE_VALUE)
		return GetLastError() == ERROR_NO_MORE_FILES;

	while (!wcscmp(findbuf.cFileName, L".") ||
			!wcscmp(findbuf.cFileName, L".."))
		if (!FindNextFileW(handle, &findbuf)) {
			DWORD err = GetLastError();
			FindClose(handle);
			return err == ERROR_NO_MORE_FILES;
		}
	FindClose(handle);
	return 0;
}

int mingw_rmdir(const char *pathname)
{
	int ret, tries = 0;
	wchar_t wpathname[MAX_PATH];
	if (xutftowcs_path(wpathname, pathname) < 0)
		return -1;

	while ((ret = _wrmdir(wpathname)) == -1 && tries < ARRAY_SIZE(delay)) {
		if (!is_file_in_use_error(GetLastError()))
			errno = err_win_to_posix(GetLastError());
		if (errno != EACCES)
			break;
		if (!is_dir_empty(wpathname)) {
			errno = ENOTEMPTY;
			break;
		}
		/*
		 * We assume that some other process had the source or
		 * destination file open at the wrong moment and retry.
		 * In order to give the other process a higher chance to
		 * complete its operation, we give up our time slice now.
		 * If we have to retry again, we do sleep a bit.
		 */
		Sleep(delay[tries]);
		tries++;
	}
	while (ret == -1 && errno == EACCES && is_file_in_use_error(GetLastError()) &&
	       ask_yes_no_if_possible("Deletion of directory '%s' failed. "
			"Should I try again?", pathname))
	       ret = _wrmdir(wpathname);
	return ret;
}

static inline int needs_hiding(const char *path)
{
	const char *basename;

	if (hide_dotfiles == HIDE_DOTFILES_FALSE)
		return 0;

	/* We cannot use basename(), as it would remove trailing slashes */
	win32_skip_dos_drive_prefix((char **)&path);
	if (!*path)
		return 0;

	for (basename = path; *path; path++)
		if (is_dir_sep(*path)) {
			do {
				path++;
			} while (is_dir_sep(*path));
			/* ignore trailing slashes */
			if (*path)
				basename = path;
			else
				break;
		}

	if (hide_dotfiles == HIDE_DOTFILES_TRUE)
		return *basename == '.';

	assert(hide_dotfiles == HIDE_DOTFILES_DOTGITONLY);
	return !strncasecmp(".git", basename, 4) &&
		(!basename[4] || is_dir_sep(basename[4]));
}

static int set_hidden_flag(const wchar_t *path, int set)
{
	DWORD original = GetFileAttributesW(path), modified;
	if (set)
		modified = original | FILE_ATTRIBUTE_HIDDEN;
	else
		modified = original & ~FILE_ATTRIBUTE_HIDDEN;
	if (original == modified || SetFileAttributesW(path, modified))
		return 0;
	errno = err_win_to_posix(GetLastError());
	return -1;
}

int mingw_mkdir(const char *path, int mode)
{
	int ret;
	wchar_t wpath[MAX_PATH];

	if (!is_valid_win32_path(path)) {
		errno = EINVAL;
		return -1;
	}

	if (xutftowcs_path(wpath, path) < 0)
		return -1;
	ret = _wmkdir(wpath);
	if (!ret && needs_hiding(path))
		return set_hidden_flag(wpath, 1);
	return ret;
}

/*
 * Calling CreateFile() using FILE_APPEND_DATA and without FILE_WRITE_DATA
 * is documented in [1] as opening a writable file handle in append mode.
 * (It is believed that) this is atomic since it is maintained by the
 * kernel unlike the O_APPEND flag which is racily maintained by the CRT.
 *
 * [1] https://docs.microsoft.com/en-us/windows/desktop/fileio/file-access-rights-constants
 *
 * This trick does not appear to work for named pipes.  Instead it creates
 * a named pipe client handle that cannot be written to.  Callers should
 * just use the regular _wopen() for them.  (And since client handle gets
 * bound to a unique server handle, it isn't really an issue.)
 */
static int mingw_open_append(wchar_t const *wfilename, int oflags, ...)
{
	HANDLE handle;
	int fd;
	DWORD create = (oflags & O_CREAT) ? OPEN_ALWAYS : OPEN_EXISTING;

	/* only these flags are supported */
	if ((oflags & ~O_CREAT) != (O_WRONLY | O_APPEND))
		return errno = ENOSYS, -1;

	/*
	 * FILE_SHARE_WRITE is required to permit child processes
	 * to append to the file.
	 */
	handle = CreateFileW(wfilename, FILE_APPEND_DATA,
			FILE_SHARE_WRITE | FILE_SHARE_READ,
			NULL, create, FILE_ATTRIBUTE_NORMAL, NULL);
	if (handle == INVALID_HANDLE_VALUE)
		return errno = err_win_to_posix(GetLastError()), -1;

	/*
	 * No O_APPEND here, because the CRT uses it only to reset the
	 * file pointer to EOF before each write(); but that is not
	 * necessary (and may lead to races) for a file created with
	 * FILE_APPEND_DATA.
	 */
	fd = _open_osfhandle((intptr_t)handle, O_BINARY);
	if (fd < 0)
		CloseHandle(handle);
	return fd;
}

/*
 * Does the pathname map to the local named pipe filesystem?
 * That is, does it have a "//./pipe/" prefix?
 */
static int is_local_named_pipe_path(const char *filename)
{
	return (is_dir_sep(filename[0]) &&
		is_dir_sep(filename[1]) &&
		filename[2] == '.'  &&
		is_dir_sep(filename[3]) &&
		!strncasecmp(filename+4, "pipe", 4) &&
		is_dir_sep(filename[8]) &&
		filename[9]);
}

int mingw_open (const char *filename, int oflags, ...)
{
	typedef int (*open_fn_t)(wchar_t const *wfilename, int oflags, ...);
	va_list args;
	unsigned mode;
	int fd, create = (oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL);
	wchar_t wfilename[MAX_PATH];
	open_fn_t open_fn;

	va_start(args, oflags);
	mode = va_arg(args, int);
	va_end(args);

	if (!is_valid_win32_path(filename)) {
		errno = create ? EINVAL : ENOENT;
		return -1;
	}

	if (filename && !strcmp(filename, "/dev/null"))
		filename = "nul";

	if ((oflags & O_APPEND) && !is_local_named_pipe_path(filename))
		open_fn = mingw_open_append;
	else
		open_fn = _wopen;

	if (xutftowcs_path(wfilename, filename) < 0)
		return -1;
	fd = open_fn(wfilename, oflags, mode);

	if (fd < 0 && (oflags & O_ACCMODE) != O_RDONLY && errno == EACCES) {
		DWORD attrs = GetFileAttributesW(wfilename);
		if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY))
			errno = EISDIR;
	}
	if ((oflags & O_CREAT) && needs_hiding(filename)) {
		/*
		 * Internally, _wopen() uses the CreateFile() API which errors
		 * out with an ERROR_ACCESS_DENIED if CREATE_ALWAYS was
		 * specified and an already existing file's attributes do not
		 * match *exactly*. As there is no mode or flag we can set that
		 * would correspond to FILE_ATTRIBUTE_HIDDEN, let's just try
		 * again *without* the O_CREAT flag (that corresponds to the
		 * CREATE_ALWAYS flag of CreateFile()).
		 */
		if (fd < 0 && errno == EACCES)
			fd = open_fn(wfilename, oflags & ~O_CREAT, mode);
		if (fd >= 0 && set_hidden_flag(wfilename, 1))
			warning("could not mark '%s' as hidden.", filename);
	}
	return fd;
}

static BOOL WINAPI ctrl_ignore(DWORD type)
{
	return TRUE;
}

#undef fgetc
int mingw_fgetc(FILE *stream)
{
	int ch;
	if (!isatty(_fileno(stream)))
		return fgetc(stream);

	SetConsoleCtrlHandler(ctrl_ignore, TRUE);
	while (1) {
		ch = fgetc(stream);
		if (ch != EOF || GetLastError() != ERROR_OPERATION_ABORTED)
			break;

		/* Ctrl+C was pressed, simulate SIGINT and retry */
		mingw_raise(SIGINT);
	}
	SetConsoleCtrlHandler(ctrl_ignore, FALSE);
	return ch;
}

#undef fopen
FILE *mingw_fopen (const char *filename, const char *otype)
{
	int hide = needs_hiding(filename);
	FILE *file;
	wchar_t wfilename[MAX_PATH], wotype[4];
	if (!is_valid_win32_path(filename)) {
		int create = otype && strchr(otype, 'w');
		errno = create ? EINVAL : ENOENT;
		return NULL;
	}
	if (filename && !strcmp(filename, "/dev/null"))
		filename = "nul";
	if (xutftowcs_path(wfilename, filename) < 0 ||
		xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0)
		return NULL;
	if (hide && !access(filename, F_OK) && set_hidden_flag(wfilename, 0)) {
		error("could not unhide %s", filename);
		return NULL;
	}
	file = _wfopen(wfilename, wotype);
	if (!file && GetLastError() == ERROR_INVALID_NAME)
		errno = ENOENT;
	if (file && hide && set_hidden_flag(wfilename, 1))
		warning("could not mark '%s' as hidden.", filename);
	return file;
}

FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream)
{
	int hide = needs_hiding(filename);
	FILE *file;
	wchar_t wfilename[MAX_PATH], wotype[4];
	if (!is_valid_win32_path(filename)) {
		int create = otype && strchr(otype, 'w');
		errno = create ? EINVAL : ENOENT;
		return NULL;
	}
	if (filename && !strcmp(filename, "/dev/null"))
		filename = "nul";
	if (xutftowcs_path(wfilename, filename) < 0 ||
		xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0)
		return NULL;
	if (hide && !access(filename, F_OK) && set_hidden_flag(wfilename, 0)) {
		error("could not unhide %s", filename);
		return NULL;
	}
	file = _wfreopen(wfilename, wotype, stream);
	if (file && hide && set_hidden_flag(wfilename, 1))
		warning("could not mark '%s' as hidden.", filename);
	return file;
}

#undef fflush
int mingw_fflush(FILE *stream)
{
	int ret = fflush(stream);

	/*
	 * write() is used behind the scenes of stdio output functions.
	 * Since git code does not check for errors after each stdio write
	 * operation, it can happen that write() is called by a later
	 * stdio function even if an earlier write() call failed. In the
	 * case of a pipe whose readable end was closed, only the first
	 * call to write() reports EPIPE on Windows. Subsequent write()
	 * calls report EINVAL. It is impossible to notice whether this
	 * fflush invocation triggered such a case, therefore, we have to
	 * catch all EINVAL errors whole-sale.
	 */
	if (ret && errno == EINVAL)
		errno = EPIPE;

	return ret;
}

#undef write
ssize_t mingw_write(int fd, const void *buf, size_t len)
{
	ssize_t result = write(fd, buf, len);

	if (result < 0 && errno == EINVAL && buf) {
		/* check if fd is a pipe */
		HANDLE h = (HANDLE) _get_osfhandle(fd);
		if (GetFileType(h) == FILE_TYPE_PIPE)
			errno = EPIPE;
		else
			errno = EINVAL;
	}

	return result;
}

int mingw_access(const char *filename, int mode)
{
	wchar_t wfilename[MAX_PATH];
	if (xutftowcs_path(wfilename, filename) < 0)
		return -1;
	/* X_OK is not supported by the MSVCRT version */
	return _waccess(wfilename, mode & ~X_OK);
}

int mingw_chdir(const char *dirname)
{
	wchar_t wdirname[MAX_PATH];
	if (xutftowcs_path(wdirname, dirname) < 0)
		return -1;
	return _wchdir(wdirname);
}

int mingw_chmod(const char *filename, int mode)
{
	wchar_t wfilename[MAX_PATH];
	if (xutftowcs_path(wfilename, filename) < 0)
		return -1;
	return _wchmod(wfilename, mode);
}

/*
 * The unit of FILETIME is 100-nanoseconds since January 1, 1601, UTC.
 * Returns the 100-nanoseconds ("hekto nanoseconds") since the epoch.
 */
static inline long long filetime_to_hnsec(const FILETIME *ft)
{
	long long winTime = ((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime;
	/* Windows to Unix Epoch conversion */
	return winTime - 116444736000000000LL;
}

static inline void filetime_to_timespec(const FILETIME *ft, struct timespec *ts)
{
	long long hnsec = filetime_to_hnsec(ft);
	ts->tv_sec = (time_t)(hnsec / 10000000);
	ts->tv_nsec = (hnsec % 10000000) * 100;
}

/**
 * Verifies that safe_create_leading_directories() would succeed.
 */
static int has_valid_directory_prefix(wchar_t *wfilename)
{
	int n = wcslen(wfilename);

	while (n > 0) {
		wchar_t c = wfilename[--n];
		DWORD attributes;

		if (!is_dir_sep(c))
			continue;

		wfilename[n] = L'\0';
		attributes = GetFileAttributesW(wfilename);
		wfilename[n] = c;
		if (attributes == FILE_ATTRIBUTE_DIRECTORY ||
				attributes == FILE_ATTRIBUTE_DEVICE)
			return 1;
		if (attributes == INVALID_FILE_ATTRIBUTES)
			switch (GetLastError()) {
			case ERROR_PATH_NOT_FOUND:
				continue;
			case ERROR_FILE_NOT_FOUND:
				/* This implies parent directory exists. */
				return 1;
			}
		return 0;
	}
	return 1;
}

/* We keep the do_lstat code in a separate function to avoid recursion.
 * When a path ends with a slash, the stat will fail with ENOENT. In
 * this case, we strip the trailing slashes and stat again.
 *
 * If follow is true then act like stat() and report on the link
 * target. Otherwise report on the link itself.
 */
static int do_lstat(int follow, const char *file_name, struct stat *buf)
{
	WIN32_FILE_ATTRIBUTE_DATA fdata;
	wchar_t wfilename[MAX_PATH];
	if (xutftowcs_path(wfilename, file_name) < 0)
		return -1;

	if (GetFileAttributesExW(wfilename, GetFileExInfoStandard, &fdata)) {
		buf->st_ino = 0;
		buf->st_gid = 0;
		buf->st_uid = 0;
		buf->st_nlink = 1;
		buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
		buf->st_size = fdata.nFileSizeLow |
			(((off_t)fdata.nFileSizeHigh)<<32);
		buf->st_dev = buf->st_rdev = 0; /* not used by Git */
		filetime_to_timespec(&(fdata.ftLastAccessTime), &(buf->st_atim));
		filetime_to_timespec(&(fdata.ftLastWriteTime), &(buf->st_mtim));
		filetime_to_timespec(&(fdata.ftCreationTime), &(buf->st_ctim));
		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
			WIN32_FIND_DATAW findbuf;
			HANDLE handle = FindFirstFileW(wfilename, &findbuf);
			if (handle != INVALID_HANDLE_VALUE) {
				if ((findbuf.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
						(findbuf.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) {
					if (follow) {
						char buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
						buf->st_size = readlink(file_name, buffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
					} else {
						buf->st_mode = S_IFLNK;
					}
					buf->st_mode |= S_IREAD;
					if (!(findbuf.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
						buf->st_mode |= S_IWRITE;
				}
				FindClose(handle);
			}
		}
		return 0;
	}
	switch (GetLastError()) {
	case ERROR_ACCESS_DENIED:
	case ERROR_SHARING_VIOLATION:
	case ERROR_LOCK_VIOLATION:
	case ERROR_SHARING_BUFFER_EXCEEDED:
		errno = EACCES;
		break;
	case ERROR_BUFFER_OVERFLOW:
		errno = ENAMETOOLONG;
		break;
	case ERROR_NOT_ENOUGH_MEMORY:
		errno = ENOMEM;
		break;
	case ERROR_PATH_NOT_FOUND:
		if (!has_valid_directory_prefix(wfilename)) {
			errno = ENOTDIR;
			break;
		}
		/* fallthru */
	default:
		errno = ENOENT;
		break;
	}
	return -1;
}

/* We provide our own lstat/fstat functions, since the provided
 * lstat/fstat functions are so slow. These stat functions are
 * tailored for Git's usage (read: fast), and are not meant to be
 * complete. Note that Git stat()s are redirected to mingw_lstat()
 * too, since Windows doesn't really handle symlinks that well.
 */
static int do_stat_internal(int follow, const char *file_name, struct stat *buf)
{
	int namelen;
	char alt_name[PATH_MAX];

	if (!do_lstat(follow, file_name, buf))
		return 0;

	/* if file_name ended in a '/', Windows returned ENOENT;
	 * try again without trailing slashes
	 */
	if (errno != ENOENT)
		return -1;

	namelen = strlen(file_name);
	if (namelen && file_name[namelen-1] != '/')
		return -1;
	while (namelen && file_name[namelen-1] == '/')
		--namelen;
	if (!namelen || namelen >= PATH_MAX)
		return -1;

	memcpy(alt_name, file_name, namelen);
	alt_name[namelen] = 0;
	return do_lstat(follow, alt_name, buf);
}

static int get_file_info_by_handle(HANDLE hnd, struct stat *buf)
{
	BY_HANDLE_FILE_INFORMATION fdata;

	if (!GetFileInformationByHandle(hnd, &fdata)) {
		errno = err_win_to_posix(GetLastError());
		return -1;
	}

	buf->st_ino = 0;
	buf->st_gid = 0;
	buf->st_uid = 0;
	buf->st_nlink = 1;
	buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
	buf->st_size = fdata.nFileSizeLow |
		(((off_t)fdata.nFileSizeHigh)<<32);
	buf->st_dev = buf->st_rdev = 0; /* not used by Git */
	filetime_to_timespec(&(fdata.ftLastAccessTime), &(buf->st_atim));
	filetime_to_timespec(&(fdata.ftLastWriteTime), &(buf->st_mtim));
	filetime_to_timespec(&(fdata.ftCreationTime), &(buf->st_ctim));
	return 0;
}

int mingw_lstat(const char *file_name, struct stat *buf)
{
	return do_stat_internal(0, file_name, buf);
}
int mingw_stat(const char *file_name, struct stat *buf)
{
	return do_stat_internal(1, file_name, buf);
}

int mingw_fstat(int fd, struct stat *buf)
{
	HANDLE fh = (HANDLE)_get_osfhandle(fd);
	DWORD avail, type = GetFileType(fh) & ~FILE_TYPE_REMOTE;

	switch (type) {
	case FILE_TYPE_DISK:
		return get_file_info_by_handle(fh, buf);

	case FILE_TYPE_CHAR:
	case FILE_TYPE_PIPE:
		/* initialize stat fields */
		memset(buf, 0, sizeof(*buf));
		buf->st_nlink = 1;

		if (type == FILE_TYPE_CHAR) {
			buf->st_mode = _S_IFCHR;
		} else {
			buf->st_mode = _S_IFIFO;
			if (PeekNamedPipe(fh, NULL, 0, NULL, &avail, NULL))
				buf->st_size = avail;
		}
		return 0;

	default:
		errno = EBADF;
		return -1;
	}
}

static inline void time_t_to_filetime(time_t t, FILETIME *ft)
{
	long long winTime = t * 10000000LL + 116444736000000000LL;
	ft->dwLowDateTime = winTime;
	ft->dwHighDateTime = winTime >> 32;
}

int mingw_utime (const char *file_name, const struct utimbuf *times)
{
	FILETIME mft, aft;
	int fh, rc;
	DWORD attrs;
	wchar_t wfilename[MAX_PATH];
	if (xutftowcs_path(wfilename, file_name) < 0)
		return -1;

	/* must have write permission */
	attrs = GetFileAttributesW(wfilename);
	if (attrs != INVALID_FILE_ATTRIBUTES &&
	    (attrs & FILE_ATTRIBUTE_READONLY)) {
		/* ignore errors here; open() will report them */
		SetFileAttributesW(wfilename, attrs & ~FILE_ATTRIBUTE_READONLY);
	}

	if ((fh = _wopen(wfilename, O_RDWR | O_BINARY)) < 0) {
		rc = -1;
		goto revert_attrs;
	}

	if (times) {
		time_t_to_filetime(times->modtime, &mft);
		time_t_to_filetime(times->actime, &aft);
	} else {
		GetSystemTimeAsFileTime(&mft);
		aft = mft;
	}
	if (!SetFileTime((HANDLE)_get_osfhandle(fh), NULL, &aft, &mft)) {
		errno = EINVAL;
		rc = -1;
	} else
		rc = 0;
	close(fh);

revert_attrs:
	if (attrs != INVALID_FILE_ATTRIBUTES &&
	    (attrs & FILE_ATTRIBUTE_READONLY)) {
		/* ignore errors again */
		SetFileAttributesW(wfilename, attrs);
	}
	return rc;
}

#undef strftime
size_t mingw_strftime(char *s, size_t max,
		      const char *format, const struct tm *tm)
{
	size_t ret = strftime(s, max, format, tm);

	if (!ret && errno == EINVAL)
		die("invalid strftime format: '%s'", format);
	return ret;
}

unsigned int sleep (unsigned int seconds)
{
	Sleep(seconds*1000);
	return 0;
}

char *mingw_mktemp(char *template)
{
	wchar_t wtemplate[MAX_PATH];
	if (xutftowcs_path(wtemplate, template) < 0)
		return NULL;
	if (!_wmktemp(wtemplate))
		return NULL;
	if (xwcstoutf(template, wtemplate, strlen(template) + 1) < 0)
		return NULL;
	return template;
}

int mkstemp(char *template)
{
	char *filename = mktemp(template);
	if (filename == NULL)
		return -1;
	return open(filename, O_RDWR | O_CREAT, 0600);
}

int gettimeofday(struct timeval *tv, void *tz)
{
	FILETIME ft;
	long long hnsec;

	GetSystemTimeAsFileTime(&ft);
	hnsec = filetime_to_hnsec(&ft);
	tv->tv_sec = hnsec / 10000000;
	tv->tv_usec = (hnsec % 10000000) / 10;
	return 0;
}

int pipe(int filedes[2])
{
	HANDLE h[2];

	/* this creates non-inheritable handles */
	if (!CreatePipe(&h[0], &h[1], NULL, 8192)) {
		errno = err_win_to_posix(GetLastError());
		return -1;
	}
	filedes[0] = _open_osfhandle(HCAST(int, h[0]), O_NOINHERIT);
	if (filedes[0] < 0) {
		CloseHandle(h[0]);
		CloseHandle(h[1]);
		return -1;
	}
	filedes[1] = _open_osfhandle(HCAST(int, h[1]), O_NOINHERIT);
	if (filedes[1] < 0) {
		close(filedes[0]);
		CloseHandle(h[1]);
		return -1;
	}
	return 0;
}

struct tm *gmtime_r(const time_t *timep, struct tm *result)
{
	if (gmtime_s(result, timep) == 0)
		return result;
	return NULL;
}

struct tm *localtime_r(const time_t *timep, struct tm *result)
{
	if (localtime_s(result, timep) == 0)
		return result;
	return NULL;
}

char *mingw_getcwd(char *pointer, int len)
{
	wchar_t cwd[MAX_PATH], wpointer[MAX_PATH];
	DWORD ret = GetCurrentDirectoryW(ARRAY_SIZE(cwd), cwd);

	if (!ret || ret >= ARRAY_SIZE(cwd)) {
		errno = ret ? ENAMETOOLONG : err_win_to_posix(GetLastError());
		return NULL;
	}
	ret = GetLongPathNameW(cwd, wpointer, ARRAY_SIZE(wpointer));
	if (!ret && GetLastError() == ERROR_ACCESS_DENIED) {
		HANDLE hnd = CreateFileW(cwd, 0,
			FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
			OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
		if (hnd == INVALID_HANDLE_VALUE)
			return NULL;
		ret = GetFinalPathNameByHandleW(hnd, wpointer, ARRAY_SIZE(wpointer), 0);
		CloseHandle(hnd);
		if (!ret || ret >= ARRAY_SIZE(wpointer))
			return NULL;
		if (xwcstoutf(pointer, normalize_ntpath(wpointer), len) < 0)
			return NULL;
		return pointer;
	}
	if (!ret || ret >= ARRAY_SIZE(wpointer))
		return NULL;
	if (xwcstoutf(pointer, wpointer, len) < 0)
		return NULL;
	convert_slashes(pointer);
	return pointer;
}

/*
 * See "Parsing C++ Command-Line Arguments" at Microsoft's Docs:
 * https://docs.microsoft.com/en-us/cpp/cpp/parsing-cpp-command-line-arguments
 */
static const char *quote_arg_msvc(const char *arg)
{
	/* count chars to quote */
	int len = 0, n = 0;
	int force_quotes = 0;
	char *q, *d;
	const char *p = arg;
	if (!*p) force_quotes = 1;
	while (*p) {
		if (isspace(*p) || *p == '*' || *p == '?' || *p == '{' || *p == '\'')
			force_quotes = 1;
		else if (*p == '"')
			n++;
		else if (*p == '\\') {
			int count = 0;
			while (*p == '\\') {
				count++;
				p++;
				len++;
			}
			if (*p == '"' || !*p)
				n += count*2 + 1;
			continue;
		}
		len++;
		p++;
	}
	if (!force_quotes && n == 0)
		return arg;

	/* insert \ where necessary */
	d = q = xmalloc(st_add3(len, n, 3));
	*d++ = '"';
	while (*arg) {
		if (*arg == '"')
			*d++ = '\\';
		else if (*arg == '\\') {
			int count = 0;
			while (*arg == '\\') {
				count++;
				*d++ = *arg++;
			}
			if (*arg == '"' || !*arg) {
				while (count-- > 0)
					*d++ = '\\';
				/* don't escape the surrounding end quote */
				if (!*arg)
					break;
				*d++ = '\\';
			}
		}
		*d++ = *arg++;
	}
	*d++ = '"';
	*d++ = '\0';
	return q;
}

#include "quote.h"

static const char *quote_arg_msys2(const char *arg)
{
	struct strbuf buf = STRBUF_INIT;
	const char *p2 = arg, *p;

	for (p = arg; *p; p++) {
		int ws = isspace(*p);
		if (!ws && *p != '\\' && *p != '"' && *p != '{' && *p != '\'' &&
		    *p != '?' && *p != '*' && *p != '~')
			continue;
		if (!buf.len)
			strbuf_addch(&buf, '"');
		if (p != p2)
			strbuf_add(&buf, p2, p - p2);
		if (*p == '\\' || *p == '"')
			strbuf_addch(&buf, '\\');
		p2 = p;
	}

	if (p == arg)
		strbuf_addch(&buf, '"');
	else if (!buf.len)
		return arg;
	else
		strbuf_add(&buf, p2, p - p2);

	strbuf_addch(&buf, '"');
	return strbuf_detach(&buf, 0);
}

static const char *parse_interpreter(const char *cmd)
{
	static char buf[100];
	char *p, *opt;
	int n, fd;

	/* don't even try a .exe */
	n = strlen(cmd);
	if (n >= 4 && !strcasecmp(cmd+n-4, ".exe"))
		return NULL;

	fd = open(cmd, O_RDONLY);
	if (fd < 0)
		return NULL;
	n = read(fd, buf, sizeof(buf)-1);
	close(fd);
	if (n < 4)	/* at least '#!/x' and not error */
		return NULL;

	if (buf[0] != '#' || buf[1] != '!')
		return NULL;
	buf[n] = '\0';
	p = buf + strcspn(buf, "\r\n");
	if (!*p)
		return NULL;

	*p = '\0';
	if (!(p = strrchr(buf+2, '/')) && !(p = strrchr(buf+2, '\\')))
		return NULL;
	/* strip options */
	if ((opt = strchr(p+1, ' ')))
		*opt = '\0';
	return p+1;
}

/*
 * exe_only means that we only want to detect .exe files, but not scripts
 * (which do not have an extension)
 */
static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
			 int isexe, int exe_only)
{
	char path[MAX_PATH];
	wchar_t wpath[MAX_PATH];
	snprintf(path, sizeof(path), "%.*s\\%s.exe", dirlen, dir, cmd);

	if (xutftowcs_path(wpath, path) < 0)
		return NULL;

	if (!isexe && _waccess(wpath, F_OK) == 0)
		return xstrdup(path);
	wpath[wcslen(wpath)-4] = '\0';
	if ((!exe_only || isexe) && _waccess(wpath, F_OK) == 0) {
		if (!(GetFileAttributesW(wpath) & FILE_ATTRIBUTE_DIRECTORY)) {
			path[strlen(path)-4] = '\0';
			return xstrdup(path);
		}
	}
	return NULL;
}

/*
 * Determines the absolute path of cmd using the split path in path.
 * If cmd contains a slash or backslash, no lookup is performed.
 */
static char *path_lookup(const char *cmd, int exe_only)
{
	const char *path;
	char *prog = NULL;
	int len = strlen(cmd);
	int isexe = len >= 4 && !strcasecmp(cmd+len-4, ".exe");

	if (strchr(cmd, '/') || strchr(cmd, '\\'))
		return xstrdup(cmd);

	path = mingw_getenv("PATH");
	if (!path)
		return NULL;

	while (!prog) {
		const char *sep = strchrnul(path, ';');
		int dirlen = sep - path;
		if (dirlen)
			prog = lookup_prog(path, dirlen, cmd, isexe, exe_only);
		if (!*sep)
			break;
		path = sep + 1;
	}

	return prog;
}

static const wchar_t *wcschrnul(const wchar_t *s, wchar_t c)
{
	while (*s && *s != c)
		s++;
	return s;
}

/* Compare only keys */
static int wenvcmp(const void *a, const void *b)
{
	wchar_t *p = *(wchar_t **)a, *q = *(wchar_t **)b;
	size_t p_len, q_len;

	/* Find the keys */
	p_len = wcschrnul(p, L'=') - p;
	q_len = wcschrnul(q, L'=') - q;

	/* If the length differs, include the shorter key's NUL */
	if (p_len < q_len)
		p_len++;
	else if (p_len > q_len)
		p_len = q_len + 1;

	return _wcsnicmp(p, q, p_len);
}

/*
 * Build an environment block combining the inherited environment
 * merged with the given list of settings.
 *
 * Values of the form "KEY=VALUE" in deltaenv override inherited values.
 * Values of the form "KEY" in deltaenv delete inherited values.
 *
 * Multiple entries in deltaenv for the same key are explicitly allowed.
 *
 * We return a contiguous block of UNICODE strings with a final trailing
 * zero word.
 */
static wchar_t *make_environment_block(char **deltaenv)
{
	wchar_t *wenv = GetEnvironmentStringsW(), *wdeltaenv, *result, *p;
	size_t wlen, s, delta_size, size;

	wchar_t **array = NULL;
	size_t alloc = 0, nr = 0, i;

	size = 1; /* for extra NUL at the end */

	/* If there is no deltaenv to apply, simply return a copy. */
	if (!deltaenv || !*deltaenv) {
		for (p = wenv; p && *p; ) {
			size_t s = wcslen(p) + 1;
			size += s;
			p += s;
		}

		ALLOC_ARRAY(result, size);
		COPY_ARRAY(result, wenv, size);
		FreeEnvironmentStringsW(wenv);
		return result;
	}

	/*
	 * If there is a deltaenv, let's accumulate all keys into `array`,
	 * sort them using the stable git_stable_qsort() and then copy,
	 * skipping duplicate keys
	 */
	for (p = wenv; p && *p; ) {
		ALLOC_GROW(array, nr + 1, alloc);
		s = wcslen(p) + 1;
		array[nr++] = p;
		p += s;
		size += s;
	}

	/* (over-)assess size needed for wchar version of deltaenv */
	for (delta_size = 0, i = 0; deltaenv[i]; i++)
		delta_size += strlen(deltaenv[i]) * 2 + 1;
	ALLOC_ARRAY(wdeltaenv, delta_size);

	/* convert the deltaenv, appending to array */
	for (i = 0, p = wdeltaenv; deltaenv[i]; i++) {
		ALLOC_GROW(array, nr + 1, alloc);
		wlen = xutftowcs(p, deltaenv[i], wdeltaenv + delta_size - p);
		array[nr++] = p;
		p += wlen + 1;
	}

	git_stable_qsort(array, nr, sizeof(*array), wenvcmp);
	ALLOC_ARRAY(result, size + delta_size);

	for (p = result, i = 0; i < nr; i++) {
		/* Skip any duplicate keys; last one wins */
		while (i + 1 < nr && !wenvcmp(array + i, array + i + 1))
		       i++;

		/* Skip "to delete" entry */
		if (!wcschr(array[i], L'='))
			continue;

		size = wcslen(array[i]) + 1;
		COPY_ARRAY(p, array[i], size);
		p += size;
	}
	*p = L'\0';

	free(array);
	free(wdeltaenv);
	FreeEnvironmentStringsW(wenv);
	return result;
}

static void do_unset_environment_variables(void)
{
	static int done;
	char *p = unset_environment_variables;

	if (done || !p)
		return;
	done = 1;

	for (;;) {
		char *comma = strchr(p, ',');

		if (comma)
			*comma = '\0';
		unsetenv(p);
		if (!comma)
			break;
		p = comma + 1;
	}
}

struct pinfo_t {
	struct pinfo_t *next;
	pid_t pid;
	HANDLE proc;
};
static struct pinfo_t *pinfo = NULL;
CRITICAL_SECTION pinfo_cs;

/* Used to match and chomp off path components */
static inline int match_last_path_component(const char *path, size_t *len,
					    const char *component)
{
	size_t component_len = strlen(component);
	if (*len < component_len + 1 ||
	    !is_dir_sep(path[*len - component_len - 1]) ||
	    fspathncmp(path + *len - component_len, component, component_len))
		return 0;
	*len -= component_len + 1;
	/* chomp off repeated dir separators */
	while (*len > 0 && is_dir_sep(path[*len - 1]))
		(*len)--;
	return 1;
}

static int is_msys2_sh(const char *cmd)
{
	if (!cmd)
		return 0;

	if (!strcmp(cmd, "sh")) {
		static int ret = -1;
		char *p;

		if (ret >= 0)
			return ret;

		p = path_lookup(cmd, 0);
		if (!p)
			ret = 0;
		else {
			size_t len = strlen(p);

			ret = match_last_path_component(p, &len, "sh.exe") &&
				match_last_path_component(p, &len, "bin") &&
				match_last_path_component(p, &len, "usr");
			free(p);
		}
		return ret;
	}

	if (ends_with(cmd, "\\sh.exe")) {
		static char *sh;

		if (!sh)
			sh = path_lookup("sh", 0);

		return !fspathcmp(cmd, sh);
	}

	return 0;
}

static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaenv,
			      const char *dir,
			      int prepend_cmd, int fhin, int fhout, int fherr)
{
	static int restrict_handle_inheritance = -1;
	STARTUPINFOEXW si;
	PROCESS_INFORMATION pi;
	LPPROC_THREAD_ATTRIBUTE_LIST attr_list = NULL;
	HANDLE stdhandles[3];
	DWORD stdhandles_count = 0;
	SIZE_T size;
	struct strbuf args;
	wchar_t wcmd[MAX_PATH], wdir[MAX_PATH], *wargs, *wenvblk = NULL;
	unsigned flags = CREATE_UNICODE_ENVIRONMENT;
	BOOL ret;
	HANDLE cons;
	const char *(*quote_arg)(const char *arg) =
		is_msys2_sh(cmd ? cmd : *argv) ?
		quote_arg_msys2 : quote_arg_msvc;

	/* Make sure to override previous errors, if any */
	errno = 0;

	if (restrict_handle_inheritance < 0)
		restrict_handle_inheritance = core_restrict_inherited_handles;
	/*
	 * The following code to restrict which handles are inherited seems
	 * to work properly only on Windows 7 and later, so let's disable it
	 * on Windows Vista and 2008.
	 */
	if (restrict_handle_inheritance < 0)
		restrict_handle_inheritance = GetVersion() >> 16 >= 7601;

	do_unset_environment_variables();

	/* Determine whether or not we are associated to a console */
	cons = CreateFileW(L"CONOUT$", GENERIC_WRITE,
			FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
			FILE_ATTRIBUTE_NORMAL, NULL);
	if (cons == INVALID_HANDLE_VALUE) {
		/* There is no console associated with this process.
		 * Since the child is a console process, Windows
		 * would normally create a console window. But
		 * since we'll be redirecting std streams, we do
		 * not need the console.
		 * It is necessary to use DETACHED_PROCESS
		 * instead of CREATE_NO_WINDOW to make ssh
		 * recognize that it has no console.
		 */
		flags |= DETACHED_PROCESS;
	} else {
		/* There is already a console. If we specified
		 * DETACHED_PROCESS here, too, Windows would
		 * disassociate the child from the console.
		 * The same is true for CREATE_NO_WINDOW.
		 * Go figure!
		 */
		CloseHandle(cons);
	}
	memset(&si, 0, sizeof(si));
	si.StartupInfo.cb = sizeof(si);
	si.StartupInfo.hStdInput = winansi_get_osfhandle(fhin);
	si.StartupInfo.hStdOutput = winansi_get_osfhandle(fhout);
	si.StartupInfo.hStdError = winansi_get_osfhandle(fherr);

	/* The list of handles cannot contain duplicates */
	if (si.StartupInfo.hStdInput != INVALID_HANDLE_VALUE)
		stdhandles[stdhandles_count++] = si.StartupInfo.hStdInput;
	if (si.StartupInfo.hStdOutput != INVALID_HANDLE_VALUE &&
	    si.StartupInfo.hStdOutput != si.StartupInfo.hStdInput)
		stdhandles[stdhandles_count++] = si.StartupInfo.hStdOutput;
	if (si.StartupInfo.hStdError != INVALID_HANDLE_VALUE &&
	    si.StartupInfo.hStdError != si.StartupInfo.hStdInput &&
	    si.StartupInfo.hStdError != si.StartupInfo.hStdOutput)
		stdhandles[stdhandles_count++] = si.StartupInfo.hStdError;
	if (stdhandles_count)
		si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;

	if (*argv && !strcmp(cmd, *argv))
		wcmd[0] = L'\0';
	else if (xutftowcs_path(wcmd, cmd) < 0)
		return -1;
	if (dir && xutftowcs_path(wdir, dir) < 0)
		return -1;

	/* concatenate argv, quoting args as we go */
	strbuf_init(&args, 0);
	if (prepend_cmd) {
		char *quoted = (char *)quote_arg(cmd);
		strbuf_addstr(&args, quoted);
		if (quoted != cmd)
			free(quoted);
	}
	for (; *argv; argv++) {
		char *quoted = (char *)quote_arg(*argv);
		if (*args.buf)
			strbuf_addch(&args, ' ');
		strbuf_addstr(&args, quoted);
		if (quoted != *argv)
			free(quoted);
	}

	ALLOC_ARRAY(wargs, st_add(st_mult(2, args.len), 1));
	xutftowcs(wargs, args.buf, 2 * args.len + 1);
	strbuf_release(&args);

	wenvblk = make_environment_block(deltaenv);

	memset(&pi, 0, sizeof(pi));
	if (restrict_handle_inheritance && stdhandles_count &&
	    (InitializeProcThreadAttributeList(NULL, 1, 0, &size) ||
	     GetLastError() == ERROR_INSUFFICIENT_BUFFER) &&
	    (attr_list = (LPPROC_THREAD_ATTRIBUTE_LIST)
			(HeapAlloc(GetProcessHeap(), 0, size))) &&
	    InitializeProcThreadAttributeList(attr_list, 1, 0, &size) &&
	    UpdateProcThreadAttribute(attr_list, 0,
				      PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
				      stdhandles,
				      stdhandles_count * sizeof(HANDLE),
				      NULL, NULL)) {
		si.lpAttributeList = attr_list;
		flags |= EXTENDED_STARTUPINFO_PRESENT;
	}

	ret = CreateProcessW(*wcmd ? wcmd : NULL, wargs, NULL, NULL,
			     stdhandles_count ? TRUE : FALSE,
			     flags, wenvblk, dir ? wdir : NULL,
			     &si.StartupInfo, &pi);

	/*
	 * On Windows 2008 R2, it seems that specifying certain types of handles
	 * (such as FILE_TYPE_CHAR or FILE_TYPE_PIPE) will always produce an
	 * error. Rather than playing finicky and fragile games, let's just try
	 * to detect this situation and simply try again without restricting any
	 * handle inheritance. This is still better than failing to create
	 * processes.
	 */
	if (!ret && restrict_handle_inheritance && stdhandles_count) {
		DWORD err = GetLastError();
		struct strbuf buf = STRBUF_INIT;

		if (err != ERROR_NO_SYSTEM_RESOURCES &&
		    /*
		     * On Windows 7 and earlier, handles on pipes and character
		     * devices are inherited automatically, and cannot be
		     * specified in the thread handle list. Rather than trying
		     * to catch each and every corner case (and running the
		     * chance of *still* forgetting a few), let's just fall
		     * back to creating the process without trying to limit the
		     * handle inheritance.
		     */
		    !(err == ERROR_INVALID_PARAMETER &&
		      GetVersion() >> 16 < 9200) &&
		    !getenv("SUPPRESS_HANDLE_INHERITANCE_WARNING")) {
			DWORD fl = 0;
			int i;

			setenv("SUPPRESS_HANDLE_INHERITANCE_WARNING", "1", 1);

			for (i = 0; i < stdhandles_count; i++) {
				HANDLE h = stdhandles[i];
				strbuf_addf(&buf, "handle #%d: %p (type %lx, "
					    "handle info (%d) %lx\n", i, h,
					    GetFileType(h),
					    GetHandleInformation(h, &fl),
					    fl);
			}
			strbuf_addstr(&buf, "\nThis is a bug; please report it "
				      "at\nhttps://github.com/git-for-windows/"
				      "git/issues/new\n\n"
				      "To suppress this warning, please set "
				      "the environment variable\n\n"
				      "\tSUPPRESS_HANDLE_INHERITANCE_WARNING=1"
				      "\n");
		}
		restrict_handle_inheritance = 0;
		flags &= ~EXTENDED_STARTUPINFO_PRESENT;
		ret = CreateProcessW(*wcmd ? wcmd : NULL, wargs, NULL, NULL,
				     TRUE, flags, wenvblk, dir ? wdir : NULL,
				     &si.StartupInfo, &pi);
		if (!ret)
			errno = err_win_to_posix(GetLastError());
		if (ret && buf.len) {
			warning("failed to restrict file handles (%ld)\n\n%s",
				err, buf.buf);
		}
		strbuf_release(&buf);
	} else if (!ret)
		errno = err_win_to_posix(GetLastError());

	if (si.lpAttributeList)
		DeleteProcThreadAttributeList(si.lpAttributeList);
	if (attr_list)
		HeapFree(GetProcessHeap(), 0, attr_list);

	free(wenvblk);
	free(wargs);

	if (!ret)
		return -1;

	CloseHandle(pi.hThread);

	/*
	 * The process ID is the human-readable identifier of the process
	 * that we want to present in log and error messages. The handle
	 * is not useful for this purpose. But we cannot close it, either,
	 * because it is not possible to turn a process ID into a process
	 * handle after the process terminated.
	 * Keep the handle in a list for waitpid.
	 */
	EnterCriticalSection(&pinfo_cs);
	{
		struct pinfo_t *info = xmalloc(sizeof(struct pinfo_t));
		info->pid = pi.dwProcessId;
		info->proc = pi.hProcess;
		info->next = pinfo;
		pinfo = info;
	}
	LeaveCriticalSection(&pinfo_cs);

	return (pid_t)pi.dwProcessId;
}

static pid_t mingw_spawnv(const char *cmd, const char **argv, int prepend_cmd)
{
	return mingw_spawnve_fd(cmd, argv, NULL, NULL, prepend_cmd, 0, 1, 2);
}

pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
		     const char *dir,
		     int fhin, int fhout, int fherr)
{
	pid_t pid;
	char *prog = path_lookup(cmd, 0);

	if (!prog) {
		errno = ENOENT;
		pid = -1;
	}
	else {
		const char *interpr = parse_interpreter(prog);

		if (interpr) {
			const char *argv0 = argv[0];
			char *iprog = path_lookup(interpr, 1);
			argv[0] = prog;
			if (!iprog) {
				errno = ENOENT;
				pid = -1;
			}
			else {
				pid = mingw_spawnve_fd(iprog, argv, deltaenv, dir, 1,
						       fhin, fhout, fherr);
				free(iprog);
			}
			argv[0] = argv0;
		}
		else
			pid = mingw_spawnve_fd(prog, argv, deltaenv, dir, 0,
					       fhin, fhout, fherr);
		free(prog);
	}
	return pid;
}

static int try_shell_exec(const char *cmd, char *const *argv)
{
	const char *interpr = parse_interpreter(cmd);
	char *prog;
	int pid = 0;

	if (!interpr)
		return 0;
	prog = path_lookup(interpr, 1);
	if (prog) {
		int exec_id;
		int argc = 0;
#ifndef _MSC_VER
		const
#endif
		char **argv2;
		while (argv[argc]) argc++;
		ALLOC_ARRAY(argv2, argc + 1);
		argv2[0] = (char *)cmd;	/* full path to the script file */
		COPY_ARRAY(&argv2[1], &argv[1], argc);
		exec_id = trace2_exec(prog, argv2);
		pid = mingw_spawnv(prog, argv2, 1);
		if (pid >= 0) {
			int status;
			if (waitpid(pid, &status, 0) < 0)
				status = 255;
			trace2_exec_result(exec_id, status);
			exit(status);
		}
		trace2_exec_result(exec_id, -1);
		pid = 1;	/* indicate that we tried but failed */
		free(prog);
		free(argv2);
	}
	return pid;
}

int mingw_execv(const char *cmd, char *const *argv)
{
	/* check if git_command is a shell script */
	if (!try_shell_exec(cmd, argv)) {
		int pid, status;
		int exec_id;

		exec_id = trace2_exec(cmd, (const char **)argv);
		pid = mingw_spawnv(cmd, (const char **)argv, 0);
		if (pid < 0) {
			trace2_exec_result(exec_id, -1);
			return -1;
		}
		if (waitpid(pid, &status, 0) < 0)
			status = 255;
		trace2_exec_result(exec_id, status);
		exit(status);
	}
	return -1;
}

int mingw_execvp(const char *cmd, char *const *argv)
{
	char *prog = path_lookup(cmd, 0);

	if (prog) {
		mingw_execv(prog, argv);
		free(prog);
	} else
		errno = ENOENT;

	return -1;
}

int mingw_kill(pid_t pid, int sig)
{
	if (pid > 0 && sig == SIGTERM) {
		HANDLE h = OpenProcess(PROCESS_TERMINATE, FALSE, pid);

		if (TerminateProcess(h, -1)) {
			CloseHandle(h);
			return 0;
		}

		errno = err_win_to_posix(GetLastError());
		CloseHandle(h);
		return -1;
	} else if (pid > 0 && sig == 0) {
		HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
		if (h) {
			CloseHandle(h);
			return 0;
		}
	}

	errno = EINVAL;
	return -1;
}

/*
 * UTF-8 versions of getenv(), putenv() and unsetenv().
 * Internally, they use the CRT's stock UNICODE routines
 * to avoid data loss.
 */
char *mingw_getenv(const char *name)
{
#define GETENV_MAX_RETAIN 64
	static char *values[GETENV_MAX_RETAIN];
	static int value_counter;
	int len_key, len_value;
	wchar_t *w_key;
	char *value;
	wchar_t w_value[32768];

	if (!name || !*name)
		return NULL;

	len_key = strlen(name) + 1;
	/* We cannot use xcalloc() here because that uses getenv() itself */
	w_key = calloc(len_key, sizeof(wchar_t));
	if (!w_key)
		die("Out of memory, (tried to allocate %u wchar_t's)", len_key);
	xutftowcs(w_key, name, len_key);
	/* GetEnvironmentVariableW() only sets the last error upon failure */
	SetLastError(ERROR_SUCCESS);
	len_value = GetEnvironmentVariableW(w_key, w_value, ARRAY_SIZE(w_value));
	if (!len_value && GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
		free(w_key);
		return NULL;
	}
	free(w_key);

	len_value = len_value * 3 + 1;
	/* We cannot use xcalloc() here because that uses getenv() itself */
	value = calloc(len_value, sizeof(char));
	if (!value)
		die("Out of memory, (tried to allocate %u bytes)", len_value);
	xwcstoutf(value, w_value, len_value);

	/*
	 * We return `value` which is an allocated value and the caller is NOT
	 * expecting to have to free it, so we keep a round-robin array,
	 * invalidating the buffer after GETENV_MAX_RETAIN getenv() calls.
	 */
	free(values[value_counter]);
	values[value_counter++] = value;
	if (value_counter >= ARRAY_SIZE(values))
		value_counter = 0;

	return value;
}

int mingw_putenv(const char *namevalue)
{
	int size;
	wchar_t *wide, *equal;
	BOOL result;

	if (!namevalue || !*namevalue)
		return 0;

	size = strlen(namevalue) * 2 + 1;
	wide = calloc(size, sizeof(wchar_t));
	if (!wide)
		die("Out of memory, (tried to allocate %u wchar_t's)", size);
	xutftowcs(wide, namevalue, size);
	equal = wcschr(wide, L'=');
	if (!equal)
		result = SetEnvironmentVariableW(wide, NULL);
	else {
		*equal = L'\0';
		result = SetEnvironmentVariableW(wide, equal + 1);
	}
	free(wide);

	if (!result)
		errno = err_win_to_posix(GetLastError());

	return result ? 0 : -1;
}

static void ensure_socket_initialization(void)
{
	WSADATA wsa;
	static int initialized = 0;

	if (initialized)
		return;

	if (WSAStartup(MAKEWORD(2,2), &wsa))
		die("unable to initialize winsock subsystem, error %d",
			WSAGetLastError());

	atexit((void(*)(void)) WSACleanup);
	initialized = 1;
}

#undef gethostname
int mingw_gethostname(char *name, int namelen)
{
    ensure_socket_initialization();
    return gethostname(name, namelen);
}

#undef gethostbyname
struct hostent *mingw_gethostbyname(const char *host)
{
	ensure_socket_initialization();
	return gethostbyname(host);
}

#undef getaddrinfo
int mingw_getaddrinfo(const char *node, const char *service,
		      const struct addrinfo *hints, struct addrinfo **res)
{
	ensure_socket_initialization();
	return getaddrinfo(node, service, hints, res);
}

int mingw_socket(int domain, int type, int protocol)
{
	int sockfd;
	SOCKET s;

	ensure_socket_initialization();
	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;
	}
	/* 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 bind
int mingw_bind(int sockfd, struct sockaddr *sa, size_t sz)
{
	SOCKET s = (SOCKET)_get_osfhandle(sockfd);
	return bind(s, sa, sz);
}

#undef setsockopt
int mingw_setsockopt(int sockfd, int lvl, int optname, void *optval, int optlen)
{
	SOCKET s = (SOCKET)_get_osfhandle(sockfd);
	return setsockopt(s, lvl, optname, (const char*)optval, optlen);
}

#undef shutdown
int mingw_shutdown(int sockfd, int how)
{
	SOCKET s = (SOCKET)_get_osfhandle(sockfd);
	return shutdown(s, how);
}

#undef listen
int mingw_listen(int sockfd, int backlog)
{
	SOCKET s = (SOCKET)_get_osfhandle(sockfd);
	return listen(s, backlog);
}

#undef accept
int mingw_accept(int sockfd1, struct sockaddr *sa, socklen_t *sz)
{
	int sockfd2;

	SOCKET s1 = (SOCKET)_get_osfhandle(sockfd1);
	SOCKET s2 = accept(s1, sa, sz);

	/* convert into a file descriptor */
	if ((sockfd2 = _open_osfhandle(s2, O_RDWR|O_BINARY)) < 0) {
		int err = errno;
		closesocket(s2);
		return error("unable to make a socket file descriptor: %s",
			strerror(err));
	}
	return sockfd2;
}

#undef rename
int mingw_rename(const char *pold, const char *pnew)
{
	DWORD attrs, gle;
	int tries = 0;
	wchar_t wpold[MAX_PATH], wpnew[MAX_PATH];
	if (xutftowcs_path(wpold, pold) < 0 || xutftowcs_path(wpnew, pnew) < 0)
		return -1;

	/*
	 * Try native rename() first to get errno right.
	 * It is based on MoveFile(), which cannot overwrite existing files.
	 */
	if (!_wrename(wpold, wpnew))
		return 0;
	if (errno != EEXIST)
		return -1;
repeat:
	if (MoveFileExW(wpold, wpnew, MOVEFILE_REPLACE_EXISTING))
		return 0;
	/* TODO: translate more errors */
	gle = GetLastError();
	if (gle == ERROR_ACCESS_DENIED &&
	    (attrs = GetFileAttributesW(wpnew)) != INVALID_FILE_ATTRIBUTES) {
		if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
			DWORD attrsold = GetFileAttributesW(wpold);
			if (attrsold == INVALID_FILE_ATTRIBUTES ||
			    !(attrsold & FILE_ATTRIBUTE_DIRECTORY))
				errno = EISDIR;
			else if (!_wrmdir(wpnew))
				goto repeat;
			return -1;
		}
		if ((attrs & FILE_ATTRIBUTE_READONLY) &&
		    SetFileAttributesW(wpnew, attrs & ~FILE_ATTRIBUTE_READONLY)) {
			if (MoveFileExW(wpold, wpnew, MOVEFILE_REPLACE_EXISTING))
				return 0;
			gle = GetLastError();
			/* revert file attributes on failure */
			SetFileAttributesW(wpnew, attrs);
		}
	}
	if (tries < ARRAY_SIZE(delay) && gle == ERROR_ACCESS_DENIED) {
		/*
		 * We assume that some other process had the source or
		 * destination file open at the wrong moment and retry.
		 * In order to give the other process a higher chance to
		 * complete its operation, we give up our time slice now.
		 * If we have to retry again, we do sleep a bit.
		 */
		Sleep(delay[tries]);
		tries++;
		goto repeat;
	}
	if (gle == ERROR_ACCESS_DENIED &&
	       ask_yes_no_if_possible("Rename from '%s' to '%s' failed. "
		       "Should I try again?", pold, pnew))
		goto repeat;

	errno = EACCES;
	return -1;
}

/*
 * Note that this doesn't return the actual pagesize, but
 * the allocation granularity. If future Windows specific git code
 * needs the real getpagesize function, we need to find another solution.
 */
int mingw_getpagesize(void)
{
	SYSTEM_INFO si;
	GetSystemInfo(&si);
	return si.dwAllocationGranularity;
}

/* See https://msdn.microsoft.com/en-us/library/windows/desktop/ms724435.aspx */
enum EXTENDED_NAME_FORMAT {
	NameDisplay = 3,
	NameUserPrincipal = 8
};

static char *get_extended_user_info(enum EXTENDED_NAME_FORMAT type)
{
	DECLARE_PROC_ADDR(secur32.dll, BOOL, GetUserNameExW,
		enum EXTENDED_NAME_FORMAT, LPCWSTR, PULONG);
	static wchar_t wbuffer[1024];
	DWORD len;

	if (!INIT_PROC_ADDR(GetUserNameExW))
		return NULL;

	len = ARRAY_SIZE(wbuffer);
	if (GetUserNameExW(type, wbuffer, &len)) {
		char *converted = xmalloc((len *= 3));
		if (xwcstoutf(converted, wbuffer, len) >= 0)
			return converted;
		free(converted);
	}

	return NULL;
}

char *mingw_query_user_email(void)
{
	return get_extended_user_info(NameUserPrincipal);
}

struct passwd *getpwuid(int uid)
{
	static unsigned initialized;
	static char user_name[100];
	static struct passwd *p;
	wchar_t buf[100];
	DWORD len;

	if (initialized)
		return p;

	len = ARRAY_SIZE(buf);
	if (!GetUserNameW(buf, &len)) {
		initialized = 1;
		return NULL;
	}

	if (xwcstoutf(user_name, buf, sizeof(user_name)) < 0) {
		initialized = 1;
		return NULL;
	}

	p = xmalloc(sizeof(*p));
	p->pw_name = user_name;
	p->pw_gecos = get_extended_user_info(NameDisplay);
	if (!p->pw_gecos)
		p->pw_gecos = "unknown";
	p->pw_dir = NULL;

	initialized = 1;
	return p;
}

static HANDLE timer_event;
static HANDLE timer_thread;
static int timer_interval;
static int one_shot;
static sig_handler_t timer_fn = SIG_DFL, sigint_fn = SIG_DFL;

/* The timer works like this:
 * The thread, ticktack(), is a trivial routine that most of the time
 * only waits to receive the signal to terminate. The main thread tells
 * the thread to terminate by setting the timer_event to the signalled
 * state.
 * But ticktack() interrupts the wait state after the timer's interval
 * length to call the signal handler.
 */

static unsigned __stdcall ticktack(void *dummy)
{
	while (WaitForSingleObject(timer_event, timer_interval) == WAIT_TIMEOUT) {
		mingw_raise(SIGALRM);
		if (one_shot)
			break;
	}
	return 0;
}

static int start_timer_thread(void)
{
	timer_event = CreateEvent(NULL, FALSE, FALSE, NULL);
	if (timer_event) {
		timer_thread = (HANDLE) _beginthreadex(NULL, 0, ticktack, NULL, 0, NULL);
		if (!timer_thread )
			return errno = ENOMEM,
				error("cannot start timer thread");
	} else
		return errno = ENOMEM,
			error("cannot allocate resources for timer");
	return 0;
}

static void stop_timer_thread(void)
{
	if (timer_event)
		SetEvent(timer_event);	/* tell thread to terminate */
	if (timer_thread) {
		int rc = WaitForSingleObject(timer_thread, 10000);
		if (rc == WAIT_TIMEOUT)
			error("timer thread did not terminate timely");
		else if (rc != WAIT_OBJECT_0)
			error("waiting for timer thread failed: %lu",
			      GetLastError());
		CloseHandle(timer_thread);
	}
	if (timer_event)
		CloseHandle(timer_event);
	timer_event = NULL;
	timer_thread = NULL;
}

static inline int is_timeval_eq(const struct timeval *i1, const struct timeval *i2)
{
	return i1->tv_sec == i2->tv_sec && i1->tv_usec == i2->tv_usec;
}

int setitimer(int type, struct itimerval *in, struct itimerval *out)
{
	static const struct timeval zero;
	static int atexit_done;

	if (out != NULL)
		return errno = EINVAL,
			error("setitimer param 3 != NULL not implemented");
	if (!is_timeval_eq(&in->it_interval, &zero) &&
	    !is_timeval_eq(&in->it_interval, &in->it_value))
		return errno = EINVAL,
			error("setitimer: it_interval must be zero or eq it_value");

	if (timer_thread)
		stop_timer_thread();

	if (is_timeval_eq(&in->it_value, &zero) &&
	    is_timeval_eq(&in->it_interval, &zero))
		return 0;

	timer_interval = in->it_value.tv_sec * 1000 + in->it_value.tv_usec / 1000;
	one_shot = is_timeval_eq(&in->it_interval, &zero);
	if (!atexit_done) {
		atexit(stop_timer_thread);
		atexit_done = 1;
	}
	return start_timer_thread();
}

int sigaction(int sig, struct sigaction *in, struct sigaction *out)
{
	if (sig != SIGALRM)
		return errno = EINVAL,
			error("sigaction only implemented for SIGALRM");
	if (out != NULL)
		return errno = EINVAL,
			error("sigaction: param 3 != NULL not implemented");

	timer_fn = in->sa_handler;
	return 0;
}

#undef signal
sig_handler_t mingw_signal(int sig, sig_handler_t handler)
{
	sig_handler_t old;

	switch (sig) {
	case SIGALRM:
		old = timer_fn;
		timer_fn = handler;
		break;

	case SIGINT:
		old = sigint_fn;
		sigint_fn = handler;
		break;

	default:
		return signal(sig, handler);
	}

	return old;
}

#undef raise
int mingw_raise(int sig)
{
	switch (sig) {
	case SIGALRM:
		if (timer_fn == SIG_DFL) {
			if (isatty(STDERR_FILENO))
				fputs("Alarm clock\n", stderr);
			exit(128 + SIGALRM);
		} else if (timer_fn != SIG_IGN)
			timer_fn(SIGALRM);
		return 0;

	case SIGINT:
		if (sigint_fn == SIG_DFL)
			exit(128 + SIGINT);
		else if (sigint_fn != SIG_IGN)
			sigint_fn(SIGINT);
		return 0;

#if defined(_MSC_VER)
	case SIGILL:
	case SIGFPE:
	case SIGSEGV:
	case SIGTERM:
	case SIGBREAK:
	case SIGABRT:
	case SIGABRT_COMPAT:
		/*
		 * The <signal.h> header in the MS C Runtime defines 8 signals
		 * as being supported on the platform. Anything else causes an
		 * "Invalid signal or error" (which in DEBUG builds causes the
		 * Abort/Retry/Ignore dialog). We by-pass the CRT for things we
		 * already know will fail.
		 */
		return raise(sig);
	default:
		errno = EINVAL;
		return -1;

#else

	default:
		return raise(sig);

#endif

	}
}

int link(const char *oldpath, const char *newpath)
{
	wchar_t woldpath[MAX_PATH], wnewpath[MAX_PATH];
	if (xutftowcs_path(woldpath, oldpath) < 0 ||
		xutftowcs_path(wnewpath, newpath) < 0)
		return -1;

	if (!CreateHardLinkW(wnewpath, woldpath, NULL)) {
		errno = err_win_to_posix(GetLastError());
		return -1;
	}
	return 0;
}

pid_t waitpid(pid_t pid, int *status, int options)
{
	HANDLE h = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION,
	    FALSE, pid);
	if (!h) {
		errno = ECHILD;
		return -1;
	}

	if (pid > 0 && options & WNOHANG) {
		if (WAIT_OBJECT_0 != WaitForSingleObject(h, 0)) {
			CloseHandle(h);
			return 0;
		}
		options &= ~WNOHANG;
	}

	if (options == 0) {
		struct pinfo_t **ppinfo;
		if (WaitForSingleObject(h, INFINITE) != WAIT_OBJECT_0) {
			CloseHandle(h);
			return 0;
		}

		if (status)
			GetExitCodeProcess(h, (LPDWORD)status);

		EnterCriticalSection(&pinfo_cs);

		ppinfo = &pinfo;
		while (*ppinfo) {
			struct pinfo_t *info = *ppinfo;
			if (info->pid == pid) {
				CloseHandle(info->proc);
				*ppinfo = info->next;
				free(info);
				break;
			}
			ppinfo = &info->next;
		}

		LeaveCriticalSection(&pinfo_cs);

		CloseHandle(h);
		return pid;
	}
	CloseHandle(h);

	errno = EINVAL;
	return -1;
}

int xutftowcsn(wchar_t *wcs, const char *utfs, size_t wcslen, int utflen)
{
	int upos = 0, wpos = 0;
	const unsigned char *utf = (const unsigned char*) utfs;
	if (!utf || !wcs || wcslen < 1) {
		errno = EINVAL;
		return -1;
	}
	/* reserve space for \0 */
	wcslen--;
	if (utflen < 0)
		utflen = INT_MAX;

	while (upos < utflen) {
		int c = utf[upos++] & 0xff;
		if (utflen == INT_MAX && c == 0)
			break;

		if (wpos >= wcslen) {
			wcs[wpos] = 0;
			errno = ERANGE;
			return -1;
		}

		if (c < 0x80) {
			/* ASCII */
			wcs[wpos++] = c;
		} else if (c >= 0xc2 && c < 0xe0 && upos < utflen &&
				(utf[upos] & 0xc0) == 0x80) {
			/* 2-byte utf-8 */
			c = ((c & 0x1f) << 6);
			c |= (utf[upos++] & 0x3f);
			wcs[wpos++] = c;
		} else if (c >= 0xe0 && c < 0xf0 && upos + 1 < utflen &&
				!(c == 0xe0 && utf[upos] < 0xa0) && /* over-long encoding */
				(utf[upos] & 0xc0) == 0x80 &&
				(utf[upos + 1] & 0xc0) == 0x80) {
			/* 3-byte utf-8 */
			c = ((c & 0x0f) << 12);
			c |= ((utf[upos++] & 0x3f) << 6);
			c |= (utf[upos++] & 0x3f);
			wcs[wpos++] = c;
		} else if (c >= 0xf0 && c < 0xf5 && upos + 2 < utflen &&
				wpos + 1 < wcslen &&
				!(c == 0xf0 && utf[upos] < 0x90) && /* over-long encoding */
				!(c == 0xf4 && utf[upos] >= 0x90) && /* > \u10ffff */
				(utf[upos] & 0xc0) == 0x80 &&
				(utf[upos + 1] & 0xc0) == 0x80 &&
				(utf[upos + 2] & 0xc0) == 0x80) {
			/* 4-byte utf-8: convert to \ud8xx \udcxx surrogate pair */
			c = ((c & 0x07) << 18);
			c |= ((utf[upos++] & 0x3f) << 12);
			c |= ((utf[upos++] & 0x3f) << 6);
			c |= (utf[upos++] & 0x3f);
			c -= 0x10000;
			wcs[wpos++] = 0xd800 | (c >> 10);
			wcs[wpos++] = 0xdc00 | (c & 0x3ff);
		} else if (c >= 0xa0) {
			/* invalid utf-8 byte, printable unicode char: convert 1:1 */
			wcs[wpos++] = c;
		} else {
			/* invalid utf-8 byte, non-printable unicode: convert to hex */
			static const char *hex = "0123456789abcdef";
			wcs[wpos++] = hex[c >> 4];
			if (wpos < wcslen)
				wcs[wpos++] = hex[c & 0x0f];
		}
	}
	wcs[wpos] = 0;
	return wpos;
}

int xwcstoutf(char *utf, const wchar_t *wcs, size_t utflen)
{
	if (!wcs || !utf || utflen < 1) {
		errno = EINVAL;
		return -1;
	}
	utflen = WideCharToMultiByte(CP_UTF8, 0, wcs, -1, utf, utflen, NULL, NULL);
	if (utflen)
		return utflen - 1;
	errno = ERANGE;
	return -1;
}

static void setup_windows_environment(void)
{
	char *tmp = getenv("TMPDIR");

	/* on Windows it is TMP and TEMP */
	if (!tmp) {
		if (!(tmp = getenv("TMP")))
			tmp = getenv("TEMP");
		if (tmp) {
			setenv("TMPDIR", tmp, 1);
			tmp = getenv("TMPDIR");
		}
	}

	if (tmp) {
		/*
		 * Convert all dir separators to forward slashes,
		 * to help shell commands called from the Git
		 * executable (by not mistaking the dir separators
		 * for escape characters).
		 */
		convert_slashes(tmp);
	}

	/* simulate TERM to enable auto-color (see color.c) */
	if (!getenv("TERM"))
		setenv("TERM", "cygwin", 1);

	/* calculate HOME if not set */
	if (!getenv("HOME")) {
		/*
		 * try $HOMEDRIVE$HOMEPATH - the home share may be a network
		 * location, thus also check if the path exists (i.e. is not
		 * disconnected)
		 */
		if ((tmp = getenv("HOMEDRIVE"))) {
			struct strbuf buf = STRBUF_INIT;
			strbuf_addstr(&buf, tmp);
			if ((tmp = getenv("HOMEPATH"))) {
				strbuf_addstr(&buf, tmp);
				if (is_directory(buf.buf))
					setenv("HOME", buf.buf, 1);
				else
					tmp = NULL; /* use $USERPROFILE */
			}
			strbuf_release(&buf);
		}
		/* use $USERPROFILE if the home share is not available */
		if (!tmp && (tmp = getenv("USERPROFILE")))
			setenv("HOME", tmp, 1);
	}
}

int is_valid_win32_path(const char *path)
{
	int preceding_space_or_period = 0, i = 0, periods = 0;

	if (!protect_ntfs)
		return 1;

	skip_dos_drive_prefix((char **)&path);

	for (;;) {
		char c = *(path++);
		switch (c) {
		case '\0':
		case '/': case '\\':
			/* cannot end in ` ` or `.`, except for `.` and `..` */
			if (preceding_space_or_period &&
			    (i != periods || periods > 2))
				return 0;
			if (!c)
				return 1;

			i = periods = preceding_space_or_period = 0;
			continue;
		case '.':
			periods++;
			/* fallthru */
		case ' ':
			preceding_space_or_period = 1;
			i++;
			continue;
		case ':': /* DOS drive prefix was already skipped */
		case '<': case '>': case '"': case '|': case '?': case '*':
			/* illegal character */
			return 0;
		default:
			if (c > '\0' && c < '\x20')
				/* illegal character */
				return 0;
		}
		preceding_space_or_period = 0;
		i++;
	}
}

#if !defined(_MSC_VER)
/*
 * Disable MSVCRT command line wildcard expansion (__getmainargs called from
 * mingw startup code, see init.c in mingw runtime).
 */
int _CRT_glob = 0;
#endif

static NORETURN void die_startup(void)
{
	fputs("fatal: not enough memory for initialization", stderr);
	exit(128);
}

static void *malloc_startup(size_t size)
{
	void *result = malloc(size);
	if (!result)
		die_startup();
	return result;
}

static char *wcstoutfdup_startup(char *buffer, const wchar_t *wcs, size_t len)
{
	len = xwcstoutf(buffer, wcs, len) + 1;
	return memcpy(malloc_startup(len), buffer, len);
}

static void maybe_redirect_std_handle(const wchar_t *key, DWORD std_id, int fd,
				      DWORD desired_access, DWORD flags)
{
	DWORD create_flag = fd ? OPEN_ALWAYS : OPEN_EXISTING;
	wchar_t buf[MAX_PATH];
	DWORD max = ARRAY_SIZE(buf);
	HANDLE handle;
	DWORD ret = GetEnvironmentVariableW(key, buf, max);

	if (!ret || ret >= max)
		return;

	/* make sure this does not leak into child processes */
	SetEnvironmentVariableW(key, NULL);
	if (!wcscmp(buf, L"off")) {
		close(fd);
		handle = GetStdHandle(std_id);
		if (handle != INVALID_HANDLE_VALUE)
			CloseHandle(handle);
		return;
	}
	if (std_id == STD_ERROR_HANDLE && !wcscmp(buf, L"2>&1")) {
		handle = GetStdHandle(STD_OUTPUT_HANDLE);
		if (handle == INVALID_HANDLE_VALUE) {
			close(fd);
			handle = GetStdHandle(std_id);
			if (handle != INVALID_HANDLE_VALUE)
				CloseHandle(handle);
		} else {
			int new_fd = _open_osfhandle((intptr_t)handle, O_BINARY);
			SetStdHandle(std_id, handle);
			dup2(new_fd, fd);
			/* do *not* close the new_fd: that would close stdout */
		}
		return;
	}
	handle = CreateFileW(buf, desired_access, 0, NULL, create_flag,
			     flags, NULL);
	if (handle != INVALID_HANDLE_VALUE) {
		int new_fd = _open_osfhandle((intptr_t)handle, O_BINARY);
		SetStdHandle(std_id, handle);
		dup2(new_fd, fd);
		close(new_fd);
	}
}

static void maybe_redirect_std_handles(void)
{
	maybe_redirect_std_handle(L"GIT_REDIRECT_STDIN", STD_INPUT_HANDLE, 0,
				  GENERIC_READ, FILE_ATTRIBUTE_NORMAL);
	maybe_redirect_std_handle(L"GIT_REDIRECT_STDOUT", STD_OUTPUT_HANDLE, 1,
				  GENERIC_WRITE, FILE_ATTRIBUTE_NORMAL);
	maybe_redirect_std_handle(L"GIT_REDIRECT_STDERR", STD_ERROR_HANDLE, 2,
				  GENERIC_WRITE, FILE_FLAG_NO_BUFFERING);
}

#ifdef _MSC_VER
#ifdef _DEBUG
#include <crtdbg.h>
#endif
#endif

/*
 * We implement wmain() and compile with -municode, which would
 * normally ignore main(), but we call the latter from the former
 * so that we can handle non-ASCII command-line parameters
 * appropriately.
 *
 * To be more compatible with the core git code, we convert
 * argv into UTF8 and pass them directly to main().
 */
int wmain(int argc, const wchar_t **wargv)
{
	int i, maxlen, exit_status;
	char *buffer, **save;
	const char **argv;

	trace2_initialize_clock();

#ifdef _MSC_VER
#ifdef _DEBUG
	_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
#endif

#ifdef USE_MSVC_CRTDBG
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
#endif

	maybe_redirect_std_handles();

	/* determine size of argv and environ conversion buffer */
	maxlen = wcslen(wargv[0]);
	for (i = 1; i < argc; i++)
		maxlen = max(maxlen, wcslen(wargv[i]));

	/* allocate buffer (wchar_t encodes to max 3 UTF-8 bytes) */
	maxlen = 3 * maxlen + 1;
	buffer = malloc_startup(maxlen);

	/*
	 * Create a UTF-8 version of w_argv. Also create a "save" copy
	 * to remember all the string pointers because parse_options()
	 * will remove claimed items from the argv that we pass down.
	 */
	ALLOC_ARRAY(argv, argc + 1);
	ALLOC_ARRAY(save, argc + 1);
	for (i = 0; i < argc; i++)
		argv[i] = save[i] = wcstoutfdup_startup(buffer, wargv[i], maxlen);
	argv[i] = save[i] = NULL;
	free(buffer);

	/* fix Windows specific environment settings */
	setup_windows_environment();

	unset_environment_variables = xstrdup("PERL5LIB");

	/* initialize critical section for waitpid pinfo_t list */
	InitializeCriticalSection(&pinfo_cs);

	/* set up default file mode and file modes for stdin/out/err */
	_fmode = _O_BINARY;
	_setmode(_fileno(stdin), _O_BINARY);
	_setmode(_fileno(stdout), _O_BINARY);
	_setmode(_fileno(stderr), _O_BINARY);

	/* initialize Unicode console */
	winansi_init();

	/* invoke the real main() using our utf8 version of argv. */
	exit_status = main(argc, argv);

	for (i = 0; i < argc; i++)
		free(save[i]);
	free(save);
	free(argv);

	return exit_status;
}

int uname(struct utsname *buf)
{
	unsigned v = (unsigned)GetVersion();
	memset(buf, 0, sizeof(*buf));
	xsnprintf(buf->sysname, sizeof(buf->sysname), "Windows");
	xsnprintf(buf->release, sizeof(buf->release),
		 "%u.%u", v & 0xff, (v >> 8) & 0xff);
	/* assuming NT variants only.. */
	xsnprintf(buf->version, sizeof(buf->version),
		  "%u", (v >> 16) & 0x7fff);
	return 0;
}
