git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH I18N filenames v2 3/3] Provide compatibility with MinGW

From
TSTimur Sufiev <timur@iris-comp.ru>
Date
Oct 28, 2009, 18:01 UTC
Message-ID
<1256752900-2615-3-git-send-email-timur@iris-comp.ru>
In-Reply-To
<1256752900-2615-2-git-send-email-timur@iris-comp.ru>
Signed-off-by: Timur Sufiev <timur@iris-comp.ru>
---
 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
Previous: Timur SufievNext: Peter Krefting
Message 3 of 6 in “Add IO-wrappers for filenames encoding <local encoding> <-> UTF-8”
  1. 1/3 Add IO-wrappers for filenames encoding <local encoding> <-> UTF-8Timur Sufiev, Oct 28, 2009
  2. 2/3 Use I18N-wrappers everywhere in GitTimur Sufiev, Oct 28, 2009
  3. 3/3 Provide compatibility with MinGWTimur Sufiev, Oct 28, 2009
  4. Peter KreftingOct 29, 2009
  5. Alex RiesenOct 29, 2009
  6. Johannes SixtOct 29, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.