Commits

René Scharfe  committed b90d9b8

work around buggy S_ISxxx(m) implementations

There are buggy implementations of S_ISxxx(m) macros on some platforms
(e.g. NetBSD). The issue is that NetBSD doesn't take care to wrap its
macro arguments in parentheses, so on Linux and sane systems we have
S_ISREG(m) defined as something like:

(((m) & S_IFMT) == S_IFREG)

But on NetBSD:

((m & _S_IFMT) == _S_IFREG)

Since a caller in builtin/diff.c called our macro as `S_IFREG | 0644'
this bug introduced a logic error on NetBSD, since the precedence of
bit-wise & is higher than | in C.

[jc: took change description from Ævar Arnfjörð Bjarmason's patch]

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

  • Participants
  • Parent commits 349362c

Comments (0)

Files changed (1)

 	else
 		return DT_UNKNOWN;
 }
-#define canon_mode(mode) \
-	(S_ISREG(mode) ? (S_IFREG | ce_permissions(mode)) : \
-	S_ISLNK(mode) ? S_IFLNK : S_ISDIR(mode) ? S_IFDIR : S_IFGITLINK)
+static inline unsigned int canon_mode(unsigned int mode)
+{
+	if (S_ISREG(mode))
+		return S_IFREG | ce_permissions(mode);
+	if (S_ISLNK(mode))
+		return S_IFLNK;
+	if (S_ISDIR(mode))
+		return S_IFDIR;
+	return S_IFGITLINK;
+}
 
 #define flexible_size(STRUCT,len) ((offsetof(struct STRUCT,name) + (len) + 8) & ~7)
 #define cache_entry_size(len) flexible_size(cache_entry,len)