Git fork

compat: convert modes to use portable file type values

This adds simple wrapper functions around calls to stat(), fstat(),
and lstat() that translate the operating system's native file type
bits to those used by most operating systems. It also rewrites the
S_IF* macros to the common values, so all file type processing is
performed using the translated modes. This makes projects portable
across operating systems that use different file type definitions.

Only the file type bits may be affected by these compatibility
functions; the file permission bits are assumed to be 07777 and are
passed through unchanged.

Signed-off-by: David Michael <fedora.dm0@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

David Michael and committed by
Junio C Hamano
d543d9c0 7fa1365c

+113 -7
+8
Makefile
··· 191 # Define NO_TRUSTABLE_FILEMODE if your filesystem may claim to support 192 # the executable mode bit, but doesn't really do so. 193 # 194 # Define NO_IPV6 if you lack IPv6 support and getaddrinfo(). 195 # 196 # Define NO_UNIX_SOCKETS if your system does not offer unix sockets. ··· 1354 endif 1355 ifdef NO_TRUSTABLE_FILEMODE 1356 BASIC_CFLAGS += -DNO_TRUSTABLE_FILEMODE 1357 endif 1358 ifdef NO_IPV6 1359 BASIC_CFLAGS += -DNO_IPV6
··· 191 # Define NO_TRUSTABLE_FILEMODE if your filesystem may claim to support 192 # the executable mode bit, but doesn't really do so. 193 # 194 + # Define NEEDS_MODE_TRANSLATION if your OS strays from the typical file type 195 + # bits in mode values (e.g. z/OS defines I_SFMT to 0xFF000000 as opposed to the 196 + # usual 0xF000). 197 + # 198 # Define NO_IPV6 if you lack IPv6 support and getaddrinfo(). 199 # 200 # Define NO_UNIX_SOCKETS if your system does not offer unix sockets. ··· 1358 endif 1359 ifdef NO_TRUSTABLE_FILEMODE 1360 BASIC_CFLAGS += -DNO_TRUSTABLE_FILEMODE 1361 + endif 1362 + ifdef NEEDS_MODE_TRANSLATION 1363 + COMPAT_CFLAGS += -DNEEDS_MODE_TRANSLATION 1364 + COMPAT_OBJS += compat/stat.o 1365 endif 1366 ifdef NO_IPV6 1367 BASIC_CFLAGS += -DNO_IPV6
-7
cache.h
··· 64 * 65 * The value 0160000 is not normally a valid mode, and 66 * also just happens to be S_IFDIR + S_IFLNK 67 - * 68 - * NOTE! We *really* shouldn't depend on the S_IFxxx macros 69 - * always having the same values everywhere. We should use 70 - * our internal git values for these things, and then we can 71 - * translate that to the OS-specific value. It just so 72 - * happens that everybody shares the same bit representation 73 - * in the UNIX world (and apparently wider too..) 74 */ 75 #define S_IFGITLINK 0160000 76 #define S_ISGITLINK(m) (((m) & S_IFMT) == S_IFGITLINK)
··· 64 * 65 * The value 0160000 is not normally a valid mode, and 66 * also just happens to be S_IFDIR + S_IFLNK 67 */ 68 #define S_IFGITLINK 0160000 69 #define S_ISGITLINK(m) (((m) & S_IFMT) == S_IFGITLINK)
+48
compat/stat.c
···
··· 1 + #define _POSIX_C_SOURCE 200112L 2 + #include <sys/stat.h> /* *stat, S_IS* */ 3 + #include <sys/types.h> /* mode_t */ 4 + 5 + static inline mode_t mode_native_to_git(mode_t native_mode) 6 + { 7 + mode_t perm_bits = native_mode & 07777; 8 + if (S_ISREG(native_mode)) 9 + return 0100000 | perm_bits; 10 + if (S_ISDIR(native_mode)) 11 + return 0040000 | perm_bits; 12 + if (S_ISLNK(native_mode)) 13 + return 0120000 | perm_bits; 14 + if (S_ISBLK(native_mode)) 15 + return 0060000 | perm_bits; 16 + if (S_ISCHR(native_mode)) 17 + return 0020000 | perm_bits; 18 + if (S_ISFIFO(native_mode)) 19 + return 0010000 | perm_bits; 20 + if (S_ISSOCK(native_mode)) 21 + return 0140000 | perm_bits; 22 + /* Non-standard type bits were given. */ 23 + return perm_bits; 24 + } 25 + 26 + int git_stat(const char *path, struct stat *buf) 27 + { 28 + int rc = stat(path, buf); 29 + if (rc == 0) 30 + buf->st_mode = mode_native_to_git(buf->st_mode); 31 + return rc; 32 + } 33 + 34 + int git_fstat(int fd, struct stat *buf) 35 + { 36 + int rc = fstat(fd, buf); 37 + if (rc == 0) 38 + buf->st_mode = mode_native_to_git(buf->st_mode); 39 + return rc; 40 + } 41 + 42 + int git_lstat(const char *path, struct stat *buf) 43 + { 44 + int rc = lstat(path, buf); 45 + if (rc == 0) 46 + buf->st_mode = mode_native_to_git(buf->st_mode); 47 + return rc; 48 + }
+23
configure.ac
··· 865 SNPRINTF_RETURNS_BOGUS= 866 fi 867 GIT_CONF_SUBST([SNPRINTF_RETURNS_BOGUS]) 868 869 870 ## Checks for library functions.
··· 865 SNPRINTF_RETURNS_BOGUS= 866 fi 867 GIT_CONF_SUBST([SNPRINTF_RETURNS_BOGUS]) 868 + # 869 + # Define NEEDS_MODE_TRANSLATION if your OS strays from the typical file type 870 + # bits in mode values. 871 + AC_CACHE_CHECK([whether the platform uses typical file type bits], 872 + [ac_cv_sane_mode_bits], [ 873 + AC_EGREP_CPP(yippeeyeswehaveit, 874 + AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT], 875 + [#if S_IFMT == 0170000 && \ 876 + S_IFREG == 0100000 && S_IFDIR == 0040000 && S_IFLNK == 0120000 && \ 877 + S_IFBLK == 0060000 && S_IFCHR == 0020000 && \ 878 + S_IFIFO == 0010000 && S_IFSOCK == 0140000 879 + yippeeyeswehaveit 880 + #endif 881 + ]), 882 + [ac_cv_sane_mode_bits=yes], 883 + [ac_cv_sane_mode_bits=no]) 884 + ]) 885 + if test $ac_cv_sane_mode_bits = yes; then 886 + NEEDS_MODE_TRANSLATION= 887 + else 888 + NEEDS_MODE_TRANSLATION=UnfortunatelyYes 889 + fi 890 + GIT_CONF_SUBST([NEEDS_MODE_TRANSLATION]) 891 892 893 ## Checks for library functions.
+34
git-compat-util.h
··· 455 #define on_disk_bytes(st) ((st).st_blocks * 512) 456 #endif 457 458 #define DEFAULT_PACKED_GIT_LIMIT \ 459 ((1024L * 1024L) * (sizeof(void*) >= 8 ? 8192 : 256)) 460
··· 455 #define on_disk_bytes(st) ((st).st_blocks * 512) 456 #endif 457 458 + #ifdef NEEDS_MODE_TRANSLATION 459 + #undef S_IFMT 460 + #undef S_IFREG 461 + #undef S_IFDIR 462 + #undef S_IFLNK 463 + #undef S_IFBLK 464 + #undef S_IFCHR 465 + #undef S_IFIFO 466 + #undef S_IFSOCK 467 + #define S_IFMT 0170000 468 + #define S_IFREG 0100000 469 + #define S_IFDIR 0040000 470 + #define S_IFLNK 0120000 471 + #define S_IFBLK 0060000 472 + #define S_IFCHR 0020000 473 + #define S_IFIFO 0010000 474 + #define S_IFSOCK 0140000 475 + #ifdef stat 476 + #undef stat 477 + #endif 478 + #define stat(path, buf) git_stat(path, buf) 479 + extern int git_stat(const char *, struct stat *); 480 + #ifdef fstat 481 + #undef fstat 482 + #endif 483 + #define fstat(fd, buf) git_fstat(fd, buf) 484 + extern int git_fstat(int, struct stat *); 485 + #ifdef lstat 486 + #undef lstat 487 + #endif 488 + #define lstat(path, buf) git_lstat(path, buf) 489 + extern int git_lstat(const char *, struct stat *); 490 + #endif 491 + 492 #define DEFAULT_PACKED_GIT_LIMIT \ 493 ((1024L * 1024L) * (sizeof(void*) >= 8 ? 8192 : 256)) 494