Signed-off-by: Timur Sufiev <timur@xxxxxxxxxxxx> --- compat/fopen.c | 5 +++-- compat/mingw.c | 37 ++++++++++++++++++++++++++++--------- compat/mingw.h | 6 +++++- compat/mkstemps.c | 3 ++- compat/win32.h | 13 +++++++++++-- io-i18n.c | 5 +++++ io-i18n.h | 7 +++++++ 7 files changed, 61 insertions(+), 15 deletions(-) diff --git a/compat/fopen.c b/compat/fopen.c index b5ca142..9136a14 100644 --- a/compat/fopen.c +++ b/compat/fopen.c @@ -10,6 +10,7 @@ */ #undef FREAD_READS_DIRECTORIES #include "../git-compat-util.h" +#include "io-i18n.h" FILE *git_fopen(const char *path, const char *mode) { @@ -17,9 +18,9 @@ FILE *git_fopen(const char *path, const char *mode) struct stat st; if (mode[0] == 'w' || mode[0] == 'a') - return fopen(path, mode); + return fopen_i18n(path, mode); - if (!(fp = fopen(path, mode))) + if (!(fp = fopen_i18n(path, mode))) return NULL; if (fstat(fileno(fp), &st)) { diff --git a/compat/mingw.c b/compat/mingw.c index 6b5b5b2..2a2ebcb 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -2,7 +2,7 @@ #include "win32.h" #include <conio.h> #include "../strbuf.h" - +#include "../io-i18n.h" #include <shellapi.h> static int err_win_to_posix(DWORD winerr) @@ -132,7 +132,7 @@ int mingw_open (const char *filename, int oflags, ...) if (!strcmp(filename, "/dev/null")) filename = "nul"; - fd = open(filename, oflags, mode); + fd = open_i18n(filename, oflags, mode); if (fd < 0 && (oflags & O_CREAT) && errno == EACCES) { DWORD attrs = GetFileAttributes(filename); @@ -253,7 +253,7 @@ int mingw_utime (const char *file_name, const struct utimbuf *times) int fh, rc; /* must have write permission */ - if ((fh = open(file_name, O_RDWR | O_BINARY)) < 0) + if ((fh = open_i18n(file_name, O_RDWR | O_BINARY)) < 0) return -1; time_t_to_filetime(times->modtime, &mft); @@ -278,7 +278,7 @@ int mkstemp(char *template) char *filename = mktemp(template); if (filename == NULL) return -1; - return open(filename, O_RDWR | O_CREAT, 0600); + return open_i18n(filename, O_RDWR | O_CREAT, 0600); } int gettimeofday(struct timeval *tv, void *tz) @@ -519,7 +519,7 @@ static const char *parse_interpreter(const char *cmd) if (n >= 4 && !strcasecmp(cmd+n-4, ".exe")) return NULL; - fd = open(cmd, O_RDONLY); + fd = open_i18n(cmd, O_RDONLY); if (fd < 0) return NULL; n = read(fd, buf, sizeof(buf)-1); @@ -1135,10 +1135,14 @@ sig_handler_t mingw_signal(int sig, sig_handler_t handler) static const char *make_backslash_path(const char *path) { static char buf[PATH_MAX + 1]; + char *out = filename_to_local(path); char *c; - if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX) - die("Too long path: %.*s", 60, path); + if ( strlcpy(buf, out ? out : path, PATH_MAX) >= PATH_MAX) { + die("Too long path: %.*s", 60, out ? out : path); + free(out); + } + free(out); for (c = buf; *c; c++) { if (*c == '/') @@ -1158,6 +1162,9 @@ int link(const char *oldpath, const char *newpath) { typedef BOOL (WINAPI *T)(const char*, const char*, LPSECURITY_ATTRIBUTES); static T create_hard_link = NULL; + char *old_out = filename_to_local(oldpath); + char *new_out = filename_to_local(newpath); + if (!create_hard_link) { create_hard_link = (T) GetProcAddress( GetModuleHandle("kernel32.dll"), "CreateHardLinkA"); @@ -1168,10 +1175,15 @@ int link(const char *oldpath, const char *newpath) errno = ENOSYS; return -1; } - if (!create_hard_link(newpath, oldpath, NULL)) { + if (!create_hard_link(new_out ? new_out : newpath, + old_out ? old_out : oldpath, NULL)) { + free(new_out); + free(old_out); errno = err_win_to_posix(GetLastError()); return -1; } + free(new_out); + free(old_out); return 0; } @@ -1206,6 +1218,7 @@ struct dirent *mingw_readdir(DIR *dir) WIN32_FIND_DATAA buf; HANDLE handle; struct mingw_DIR *mdir = (struct mingw_DIR*)dir; + char *out; if (!dir->dd_handle) { errno = EBADF; /* No set_errno for mingw */ @@ -1236,7 +1249,13 @@ struct dirent *mingw_readdir(DIR *dir) } /* We get here if `buf' contains valid data. */ - strcpy(dir->dd_dir.d_name, buf.cFileName); + out = filename_to_utf8(buf.cFileName); + if ( strlcpy(dir->dd_dir.d_name, + out ? out : buf.cFileName, FILENAME_MAX) >= FILENAME_MAX) { + die("Too long dir entry name: %.*s", 60, + out ? out : buf.cFileName); + free(out); + } ++dir->dd_stat; /* Set file type, based on WIN32_FIND_DATA */ diff --git a/compat/mingw.h b/compat/mingw.h index 5b5258b..2447aa7 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -1,4 +1,7 @@ +#ifndef GIT_MINGW_H +#define GIT_MINGW_H #include <winsock2.h> +#include "../io-i18n.h" /* * things that are not available in header files @@ -112,7 +115,7 @@ static inline int mingw_unlink(const char *pathname) { /* read-only files cannot be removed */ chmod(pathname, 0666); - return unlink(pathname); + return unlink_i18n(pathname); } #define unlink mingw_unlink @@ -273,3 +276,4 @@ struct mingw_dirent #define readdir(x) mingw_readdir(x) struct dirent *mingw_readdir(DIR *dir); #endif // !NO_MINGW_REPLACE_READDIR +#endif // GIT_MINGW_H diff --git a/compat/mkstemps.c b/compat/mkstemps.c index 14179c8..0cdd42d 100644 --- a/compat/mkstemps.c +++ b/compat/mkstemps.c @@ -1,4 +1,5 @@ #include "../git-compat-util.h" +#include "../io-i18n.h" /* Adapted from libiberty's mkstemp.c. */ @@ -47,7 +48,7 @@ int gitmkstemps(char *pattern, int suffix_len) template[4] = letters[v % num_letters]; v /= num_letters; template[5] = letters[v % num_letters]; v /= num_letters; - fd = open(pattern, O_CREAT | O_EXCL | O_RDWR, 0600); + fd = open_i18n(pattern, O_CREAT | O_EXCL | O_RDWR, 0600); if (fd > 0) return fd; /* diff --git a/compat/win32.h b/compat/win32.h index 8ce9104..f71e36d 100644 --- a/compat/win32.h +++ b/compat/win32.h @@ -20,8 +20,17 @@ static inline int file_attr_to_st_mode (DWORD attr) static inline int get_file_attr(const char *fname, WIN32_FILE_ATTRIBUTE_DATA *fdata) { - if (GetFileAttributesExA(fname, GetFileExInfoStandard, fdata)) - return 0; + char *out = filename_to_local(fname); + int ret; + + if ( out != NULL ) { + ret = GetFileAttributesExA(out, GetFileExInfoStandard, fdata); + free(out); + } else + ret = GetFileAttributesExA(fname, GetFileExInfoStandard, fdata); + + if ( ret ) + return 0; switch (GetLastError()) { case ERROR_ACCESS_DENIED: diff --git a/io-i18n.c b/io-i18n.c index ed88a68..63e88b8 100644 --- a/io-i18n.c +++ b/io-i18n.c @@ -84,6 +84,7 @@ char *filename_to_local(const char *filename) #endif } +#ifndef __USE_MINGW_ACCESS #undef stat int stat_i18n(const char *filename, struct stat *buf) { @@ -127,6 +128,7 @@ int link_i18n(const char *oldname, const char *newname) free(new_out); return ret; } +#endif // __USE_MINGW_ACCESS #undef open int open_i18n(const char *filename, int flags, ...) @@ -165,6 +167,8 @@ int unlink_i18n(const char *filename) return ret; } +#if !defined(__USE_MINGW_ACCESS) || \ + (defined(__USE_MINGW_ACCESS) && defined(NO_MINGW_REPLACE_READDIR)) #undef readdir struct dirent *readdir_i18n(DIR * dirstream) { @@ -187,6 +191,7 @@ struct dirent *readdir_i18n(DIR * dirstream) } else return NULL; } +#endif #undef opendir DIR *opendir_i18n(const char *dirname) diff --git a/io-i18n.h b/io-i18n.h index 2369d31..38f73b3 100644 --- a/io-i18n.h +++ b/io-i18n.h @@ -23,11 +23,18 @@ int unlink_i18n(const char *filename); #define opendir(a) opendir_i18n(a) #define fopen(a, b) fopen_i18n(a, b) #define chmod(a, b) chmod_i18n(a, b) + +#ifndef __USE_MINGW_ACCESS #define open open_i18n #define stat(a, b) stat_i18n(a, b) #define lstat(a, b) lstat_i18n(a, b) #define readdir(a) readdir_i18n(a) #define unlink(a) unlink_i18n(a) #define link(a, b) link_i18n(a, b) +#endif // __USE_MINGW_ACCESS + +#if defined(__USE_MINGW_ACCESS) && defined(NO_MINGW_REPLACE_READDIR) +#define readdir(a) readdir_i18n(a) +#endif #endif /* GIT_IO_I18N_H */ -- 1.6.5.1 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html