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

Re: [PATCH] Use FIX_UTF8_MAC to enable conversion from UTF8-MAC to UTF8

From
Mark Junker <mjscod@web.de>
Date
Jan 21, 2008, 11:43 UTC
Message-ID
<fn20he$c4e$1@ger.gmane.org>
In-Reply-To
<7vejcbzbge.fsf@gitster.siamese.dyndns.org>
Junio C Hamano schrieb:
Show 9 quoted lines
> You memcpy() what the library gave you in *result to the
> statically allocated "temp".  d_name[] in "temp" comes from the
> structure definition in the user visible include file, which
> could be much shorter than what the library gave you in *result.
> The structure definition I showed in my message you are
> responding to illustrates the issue.  If MacOS uses a similar
> trick to define d_name[256] and sometimes returns much longer
> name in *result, you are truncating the name by copying only the
> first part of the structure and first 256 bytes of d_name[]. 

Now I understand what you mean. Ok, I'll try to change this and make this work on other platforms too.

I didn't know that the readdir function is allowed to return something longer for d_name than the specified length.

Regards, Mark

From 239de834a4d67b4176a8dbf5504fa2f335989aaa Mon Sep 17 00:00:00 2001
From: Mark Junker <mjscod@web.de>
Date: Sun, 20 Jan 2008 16:59:32 +0100
Subject: [PATCH] Use FIX_UTF8_MAC to enable conversion from UTF8-MAC to UTF8
Signed-off-by: Mark Junker <mjscod@web.de>
---
 Makefile          |    5 +++++
 compat/readdir.c  |   30 ++++++++++++++++++++++++++++++
 git-compat-util.h |    5 +++++
 setup.c           |   12 ++++++++++++
 4 files changed, 52 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
index 5aac0c0..e55914e 100644
--- a/Makefile
+++ b/Makefile
@@ -417,6 +417,7 @@ ifeq ($(uname_S),Darwin)
 	endif
 	NO_STRLCPY = YesPlease
 	NO_MEMMEM = YesPlease
+	FIX_UTF8_MAC = YesPlease
 endif
 ifeq ($(uname_S),SunOS)
 	NEEDS_SOCKET = YesPlease
@@ -616,6 +617,10 @@ ifdef NO_STRLCPY
 	COMPAT_CFLAGS += -DNO_STRLCPY
 	COMPAT_OBJS += compat/strlcpy.o
 endif
+ifdef FIX_UTF8_MAC
+	COMPAT_CFLAGS += -DFIX_UTF8_MAC
+	COMPAT_OBJS += compat/readdir.o
+endif
 ifdef NO_STRTOUMAX
 	COMPAT_CFLAGS += -DNO_STRTOUMAX
 	COMPAT_OBJS += compat/strtoumax.o
diff --git a/compat/readdir.c b/compat/readdir.c
new file mode 100644
index 0000000..96a724a
--- /dev/null
+++ b/compat/readdir.c
@@ -0,0 +1,30 @@
+#include "../git-compat-util.h"
+#include "../utf8.h"
+
+#undef readdir
+
+static struct dirent *temp_dirent = NULL;
+static size_t temp_dirent_length = 0;
+
+struct dirent *gitreaddir(DIR *dirp)
+{
+	struct dirent *result = readdir(dirp);
+	if (result != NULL) {
+		char *utf8 = reencode_string(result->d_name, "UTF8", "UTF8-MAC");
+		if (utf8 != NULL) {
+			size_t utf8_len = strlen(utf8);
+			/* Create a copy of the dirent data only if conversion is possible. */
+			if (result->d_reclen > temp_dirent_length) {
+				/* Ensure that the buffer is large enough and avoid
+				 * too much allocations. */
+				temp_dirent_length = result->d_reclen;
+				temp_dirent = realloc(temp_dirent, temp_dirent_length);
+			}
+			memcpy(temp_dirent, result, result->d_reclen);
+			memcpy(temp_dirent->d_name, utf8, utf8_len + 1);
+			free(utf8);
+			result = temp_dirent;
+		}
+	}
+	return result;
+}
diff --git a/git-compat-util.h b/git-compat-util.h
index b6ef544..cd0233d 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -202,6 +202,11 @@ void *gitmemmem(const void *haystack, size_t haystacklen,
                 const void *needle, size_t needlelen);
 #endif
 
+#ifdef FIX_UTF8_MAC
+#define readdir gitreaddir
+struct dirent *gitreaddir(DIR *dirp);
+#endif
+
 #ifdef __GLIBC_PREREQ
 #if __GLIBC_PREREQ(2, 1)
 #define HAVE_STRCHRNUL
diff --git a/setup.c b/setup.c
index adede16..4cec28b 100644
--- a/setup.c
+++ b/setup.c
@@ -1,5 +1,8 @@
 #include "cache.h"
 #include "dir.h"
+#ifdef FIX_UTF8_MAC
+#include "utf8.h"
+#endif
 
 static int inside_git_dir = -1;
 static int inside_work_tree = -1;
@@ -131,6 +134,15 @@ const char **get_pathspec(const char *prefix, const char **pathspec)
 	p = pathspec;
 	prefixlen = prefix ? strlen(prefix) : 0;
 	do {
+#ifdef FIX_UTF8_MAC
+		/* Reencode as UTF8 (composed) to have a counterpart for the
+		 * readdir-replacement on MacOS X.
+		 */
+		char *utf8 = reencode_string(entry, "UTF8", "UTF8-MAC");
+		if (utf8 != NULL) {
+			entry = utf8;
+		}
+#endif
 		*p = prefix_path(prefix, prefixlen, entry);
 	} while ((entry = *++p) != NULL);
 	return (const char **) pathspec;
-- 
1.5.4.rc3.38.g8166
Previous: Junio C HamanoNext: H. Peter Anvin
Message 8 of 22 in “Use FIX_UTF8_MAC to enable conversion from UTF8-MAC to UTF8”
  1. Use FIX_UTF8_MAC to enable conversion from UTF8-MAC to UTF8Mark Junker, Jan 21, 2008
  2. Mark JunkerJan 21, 2008
  3. Mark JunkerJan 21, 2008
  4. Mark JunkerJan 21, 2008
  5. Junio C HamanoJan 21, 2008
  6. Mark JunkerJan 21, 2008
  7. Junio C HamanoJan 21, 2008
  8. Mark JunkerJan 21, 2008
  9. H. Peter AnvinJan 22, 2008
  10. Linus TorvaldsJan 22, 2008
  11. Linus TorvaldsJan 22, 2008
  12. Junio C HamanoJan 22, 2008
  13. Robin RosenbergJan 22, 2008
  14. Dmitry PotapovJan 22, 2008
  15. Dmitry PotapovJan 22, 2008
  16. Nicolas PitreJan 22, 2008
  17. Linus TorvaldsJan 22, 2008
  18. Johannes SchindelinJan 21, 2008
  19. Junio C HamanoJan 21, 2008
  20. Mark JunkerJan 21, 2008
  21. Johannes SchindelinJan 21, 2008
  22. Johannes SchindelinJan 21, 2008

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.