diff options
Diffstat (limited to 'compat')
-rw-r--r-- | compat/mingw.c | 2 | ||||
-rw-r--r-- | compat/mingw.h | 1 | ||||
-rw-r--r-- | compat/open.c | 25 | ||||
-rw-r--r-- | compat/precompose_utf8.c | 52 | ||||
-rw-r--r-- | compat/precompose_utf8.h | 2 |
5 files changed, 62 insertions, 20 deletions
diff --git a/compat/mingw.c b/compat/mingw.c index a00f331230..a43599841c 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -367,6 +367,8 @@ int mingw_rmdir(const char *pathname) ask_yes_no_if_possible("Deletion of directory '%s' failed. " "Should I try again?", pathname)) ret = _wrmdir(wpathname); + if (!ret) + invalidate_lstat_cache(); return ret; } diff --git a/compat/mingw.h b/compat/mingw.h index af8eddd73e..c9a52ad64a 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -227,6 +227,7 @@ int mingw_rmdir(const char *path); int mingw_open (const char *filename, int oflags, ...); #define open mingw_open +#undef OPEN_RETURNS_EINTR int mingw_fgetc(FILE *stream); #define fgetc mingw_fgetc diff --git a/compat/open.c b/compat/open.c new file mode 100644 index 0000000000..eb3754a23b --- /dev/null +++ b/compat/open.c @@ -0,0 +1,25 @@ +#include "git-compat-util.h" + +#undef open +int git_open_with_retry(const char *path, int flags, ...) +{ + mode_t mode = 0; + int ret; + + /* + * Also O_TMPFILE would take a mode, but it isn't defined everywhere. + * And anyway, we don't use it in our code base. + */ + if (flags & O_CREAT) { + va_list ap; + va_start(ap, flags); + mode = va_arg(ap, int); + va_end(ap); + } + + do { + ret = open(path, flags, mode); + } while (ret < 0 && errno == EINTR); + + return ret; +} diff --git a/compat/precompose_utf8.c b/compat/precompose_utf8.c index 136250fbf6..ec560565a8 100644 --- a/compat/precompose_utf8.c +++ b/compat/precompose_utf8.c @@ -60,32 +60,46 @@ void probe_utf8_pathname_composition(void) strbuf_release(&path); } - -void precompose_argv(int argc, const char **argv) +static inline const char *precompose_string_if_needed(const char *in) { - int i = 0; - const char *oldarg; - char *newarg; - iconv_t ic_precompose; + size_t inlen; + size_t outlen; + if (has_non_ascii(in, (size_t)-1, &inlen)) { + iconv_t ic_prec; + char *out; + if (precomposed_unicode < 0) + git_config_get_bool("core.precomposeunicode", &precomposed_unicode); + if (precomposed_unicode != 1) + return in; + ic_prec = iconv_open(repo_encoding, path_encoding); + if (ic_prec == (iconv_t) -1) + return in; + + out = reencode_string_iconv(in, inlen, ic_prec, 0, &outlen); + if (out) { + if (outlen == inlen && !memcmp(in, out, outlen)) + free(out); /* no need to return indentical */ + else + in = out; + } + iconv_close(ic_prec); - if (precomposed_unicode != 1) - return; + } + return in; +} - ic_precompose = iconv_open(repo_encoding, path_encoding); - if (ic_precompose == (iconv_t) -1) - return; +const char *precompose_argv_prefix(int argc, const char **argv, const char *prefix) +{ + int i = 0; while (i < argc) { - size_t namelen; - oldarg = argv[i]; - if (has_non_ascii(oldarg, (size_t)-1, &namelen)) { - newarg = reencode_string_iconv(oldarg, namelen, ic_precompose, 0, NULL); - if (newarg) - argv[i] = newarg; - } + argv[i] = precompose_string_if_needed(argv[i]); i++; } - iconv_close(ic_precompose); + if (prefix) { + prefix = precompose_string_if_needed(prefix); + } + return prefix; } diff --git a/compat/precompose_utf8.h b/compat/precompose_utf8.h index 6f843d3e1a..d70b84665c 100644 --- a/compat/precompose_utf8.h +++ b/compat/precompose_utf8.h @@ -28,7 +28,7 @@ typedef struct { struct dirent_prec_psx *dirent_nfc; } PREC_DIR; -void precompose_argv(int argc, const char **argv); +const char *precompose_argv_prefix(int argc, const char **argv, const char *prefix); void probe_utf8_pathname_composition(void); PREC_DIR *precompose_utf8_opendir(const char *dirname); |