summaryrefslogtreecommitdiff
path: root/compat/mingw.c
diff options
context:
space:
mode:
Diffstat (limited to 'compat/mingw.c')
-rw-r--r--compat/mingw.c151
1 files changed, 120 insertions, 31 deletions
diff --git a/compat/mingw.c b/compat/mingw.c
index 901375d584..6b06ea540f 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -6,10 +6,16 @@
#include <wchar.h>
#include "../strbuf.h"
#include "../run-command.h"
-#include "../cache.h"
+#include "../abspath.h"
+#include "../alloc.h"
#include "win32/lazyload.h"
#include "../config.h"
+#include "../environment.h"
+#include "../trace2.h"
+#include "../symlinks.h"
+#include "../wrapper.h"
#include "dir.h"
+#include "gettext.h"
#define SECURITY_WIN32
#include <sspi.h>
@@ -196,16 +202,19 @@ static int read_yes_no_answer(void)
static int ask_yes_no_if_possible(const char *format, ...)
{
char question[4096];
- const char *retry_hook[] = { NULL, NULL, NULL };
+ const char *retry_hook;
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);
+ retry_hook = mingw_getenv("GIT_ASK_YESNO");
+ if (retry_hook) {
+ struct child_process cmd = CHILD_PROCESS_INIT;
+
+ strvec_pushl(&cmd.args, retry_hook, question, NULL);
+ return !run_command(&cmd);
}
if (!isatty(_fileno(stdin)) || !isatty(_fileno(stderr)))
@@ -234,7 +243,8 @@ 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)
+int mingw_core_config(const char *var, const char *value,
+ const struct config_context *ctx, void *cb)
{
if (!strcmp(var, "core.hidedotfiles")) {
if (value && !strcasecmp(value, "dotgitonly"))
@@ -245,6 +255,8 @@ int mingw_core_config(const char *var, const char *value, void *cb)
}
if (!strcmp(var, "core.unsetenvvars")) {
+ if (!value)
+ return config_error_nonbool(var);
free(unset_environment_variables);
unset_environment_variables = xstrdup(value);
return 0;
@@ -695,13 +707,24 @@ 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) {
+ if (result < 0 && (errno == EINVAL || errno == ENOSPC) && buf) {
+ int orig = errno;
+
/* check if fd is a pipe */
HANDLE h = (HANDLE) _get_osfhandle(fd);
- if (GetFileType(h) == FILE_TYPE_PIPE)
+ if (GetFileType(h) != FILE_TYPE_PIPE)
+ errno = orig;
+ else if (orig == EINVAL)
errno = EPIPE;
- else
- errno = EINVAL;
+ else {
+ DWORD buf_size;
+
+ if (!GetNamedPipeInfo(h, NULL, NULL, &buf_size, NULL))
+ buf_size = 4096;
+ if (len > buf_size)
+ return write(fd, buf, buf_size);
+ errno = orig;
+ }
}
return result;
@@ -1337,6 +1360,11 @@ static char *path_lookup(const char *cmd, int exe_only)
return prog;
}
+char *mingw_locate_in_PATH(const char *cmd)
+{
+ return path_lookup(cmd, 0);
+}
+
static const wchar_t *wcschrnul(const wchar_t *s, wchar_t c)
{
while (*s && *s != c)
@@ -1393,8 +1421,7 @@ static wchar_t *make_environment_block(char **deltaenv)
p += s;
}
- ALLOC_ARRAY(result, size);
- COPY_ARRAY(result, wenv, size);
+ DUP_ARRAY(result, wenv, size);
FreeEnvironmentStringsW(wenv);
return result;
}
@@ -1836,16 +1863,13 @@ static int try_shell_exec(const char *cmd, char *const *argv)
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);
+ exec_id = trace2_exec(prog, (const char **)argv2);
+ pid = mingw_spawnv(prog, (const char **)argv2, 1);
if (pid >= 0) {
int status;
if (waitpid(pid, &status, 0) < 0)
@@ -2671,6 +2695,30 @@ static PSID get_current_user_sid(void)
return result;
}
+static BOOL user_sid_to_user_name(PSID sid, LPSTR *str)
+{
+ SID_NAME_USE pe_use;
+ DWORD len_user = 0, len_domain = 0;
+ BOOL translate_sid_to_user;
+
+ /*
+ * returns only FALSE, because the string pointers are NULL
+ */
+ LookupAccountSidA(NULL, sid, NULL, &len_user, NULL, &len_domain,
+ &pe_use);
+ /*
+ * Alloc needed space of the strings
+ */
+ ALLOC_ARRAY((*str), (size_t)len_domain + (size_t)len_user);
+ translate_sid_to_user = LookupAccountSidA(NULL, sid,
+ (*str) + len_domain, &len_user, *str, &len_domain, &pe_use);
+ if (!translate_sid_to_user)
+ FREE_AND_NULL(*str);
+ else
+ (*str)[len_domain] = '/';
+ return translate_sid_to_user;
+}
+
static int acls_supported(const char *path)
{
size_t offset = offset_1st_component(path);
@@ -2749,30 +2797,50 @@ int is_path_owned_by_current_sid(const char *path, struct strbuf *report)
/*
* On FAT32 volumes, ownership is not actually recorded.
*/
- strbuf_addf(report, "'%s' is on a file system that does"
+ strbuf_addf(report, "'%s' is on a file system that does "
"not record ownership\n", path);
} else if (report) {
- LPSTR str1, str2, to_free1 = NULL, to_free2 = NULL;
+ LPSTR str1, str2, str3, str4, to_free1 = NULL,
+ to_free3 = NULL, to_local_free2 = NULL,
+ to_local_free4 = NULL;
- if (ConvertSidToStringSidA(sid, &str1))
+ if (user_sid_to_user_name(sid, &str1))
to_free1 = str1;
else
str1 = "(inconvertible)";
-
- if (!current_user_sid)
- str2 = "(none)";
- else if (!IsValidSid(current_user_sid))
- str2 = "(invalid)";
- else if (ConvertSidToStringSidA(current_user_sid, &str2))
- to_free2 = str2;
+ if (ConvertSidToStringSidA(sid, &str2))
+ to_local_free2 = str2;
else
str2 = "(inconvertible)";
+
+ if (!current_user_sid) {
+ str3 = "(none)";
+ str4 = "(none)";
+ }
+ else if (!IsValidSid(current_user_sid)) {
+ str3 = "(invalid)";
+ str4 = "(invalid)";
+ } else {
+ if (user_sid_to_user_name(current_user_sid,
+ &str3))
+ to_free3 = str3;
+ else
+ str3 = "(inconvertible)";
+ if (ConvertSidToStringSidA(current_user_sid,
+ &str4))
+ to_local_free4 = str4;
+ else
+ str4 = "(inconvertible)";
+ }
strbuf_addf(report,
"'%s' is owned by:\n"
- "\t'%s'\nbut the current user is:\n"
- "\t'%s'\n", path, str1, str2);
- LocalFree(to_free1);
- LocalFree(to_free2);
+ "\t%s (%s)\nbut the current user is:\n"
+ "\t%s (%s)\n",
+ path, str1, str2, str3, str4);
+ free(to_free1);
+ LocalFree(to_local_free2);
+ free(to_free3);
+ LocalFree(to_local_free4);
}
}
@@ -3090,3 +3158,24 @@ int uname(struct utsname *buf)
"%u", (v >> 16) & 0x7fff);
return 0;
}
+
+#ifndef NO_UNIX_SOCKETS
+int mingw_have_unix_sockets(void)
+{
+ SC_HANDLE scm, srvc;
+ SERVICE_STATUS_PROCESS status;
+ DWORD bytes;
+ int ret = 0;
+ scm = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
+ if (scm) {
+ srvc = OpenServiceA(scm, "afunix", SERVICE_QUERY_STATUS);
+ if (srvc) {
+ if(QueryServiceStatusEx(srvc, SC_STATUS_PROCESS_INFO, (LPBYTE)&status, sizeof(SERVICE_STATUS_PROCESS), &bytes))
+ ret = status.dwCurrentState == SERVICE_RUNNING;
+ CloseServiceHandle(srvc);
+ }
+ CloseServiceHandle(scm);
+ }
+ return ret;
+}
+#endif