diff options
Diffstat (limited to 'compat/mingw.c')
-rw-r--r-- | compat/mingw.c | 110 |
1 files changed, 93 insertions, 17 deletions
diff --git a/compat/mingw.c b/compat/mingw.c index ec5280d..4876344 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -255,6 +255,8 @@ int mingw_core_config(const char *var, const char *value, } if (!strcmp(var, "core.unsetenvvars")) { + if (!value) + return config_error_nonbool(var); free(unset_environment_variables); unset_environment_variables = xstrdup(value); return 0; @@ -705,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; @@ -2682,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); @@ -2763,27 +2800,47 @@ int is_path_owned_by_current_sid(const char *path, struct strbuf *report) 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); } } @@ -3101,3 +3158,22 @@ int uname(struct utsname *buf) "%u", (v >> 16) & 0x7fff); return 0; } + +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; +} |