···191191# Define NO_TRUSTABLE_FILEMODE if your filesystem may claim to support
192192# the executable mode bit, but doesn't really do so.
193193#
194194+# Define NEEDS_MODE_TRANSLATION if your OS strays from the typical file type
195195+# bits in mode values (e.g. z/OS defines I_SFMT to 0xFF000000 as opposed to the
196196+# usual 0xF000).
197197+#
194198# Define NO_IPV6 if you lack IPv6 support and getaddrinfo().
195199#
196200# Define NO_UNIX_SOCKETS if your system does not offer unix sockets.
···12291233endif
12301234ifdef NO_TRUSTABLE_FILEMODE
12311235 BASIC_CFLAGS += -DNO_TRUSTABLE_FILEMODE
12361236+endif
12371237+ifdef NEEDS_MODE_TRANSLATION
12381238+ COMPAT_CFLAGS += -DNEEDS_MODE_TRANSLATION
12391239+ COMPAT_OBJS += compat/stat.o
12321240endif
12331241ifdef NO_IPV6
12341242 BASIC_CFLAGS += -DNO_IPV6
-7
cache.h
···6565 *
6666 * The value 0160000 is not normally a valid mode, and
6767 * also just happens to be S_IFDIR + S_IFLNK
6868- *
6969- * NOTE! We *really* shouldn't depend on the S_IFxxx macros
7070- * always having the same values everywhere. We should use
7171- * our internal git values for these things, and then we can
7272- * translate that to the OS-specific value. It just so
7373- * happens that everybody shares the same bit representation
7474- * in the UNIX world (and apparently wider too..)
7568 */
7669#define S_IFGITLINK 0160000
7770#define S_ISGITLINK(m) (((m) & S_IFMT) == S_IFGITLINK)
+48
compat/stat.c
···11+#define _POSIX_C_SOURCE 200112L
22+#include <sys/stat.h> /* *stat, S_IS* */
33+#include <sys/types.h> /* mode_t */
44+55+static inline mode_t mode_native_to_git(mode_t native_mode)
66+{
77+ mode_t perm_bits = native_mode & 07777;
88+ if (S_ISREG(native_mode))
99+ return 0100000 | perm_bits;
1010+ if (S_ISDIR(native_mode))
1111+ return 0040000 | perm_bits;
1212+ if (S_ISLNK(native_mode))
1313+ return 0120000 | perm_bits;
1414+ if (S_ISBLK(native_mode))
1515+ return 0060000 | perm_bits;
1616+ if (S_ISCHR(native_mode))
1717+ return 0020000 | perm_bits;
1818+ if (S_ISFIFO(native_mode))
1919+ return 0010000 | perm_bits;
2020+ if (S_ISSOCK(native_mode))
2121+ return 0140000 | perm_bits;
2222+ /* Non-standard type bits were given. */
2323+ return perm_bits;
2424+}
2525+2626+int git_stat(const char *path, struct stat *buf)
2727+{
2828+ int rc = stat(path, buf);
2929+ if (rc == 0)
3030+ buf->st_mode = mode_native_to_git(buf->st_mode);
3131+ return rc;
3232+}
3333+3434+int git_fstat(int fd, struct stat *buf)
3535+{
3636+ int rc = fstat(fd, buf);
3737+ if (rc == 0)
3838+ buf->st_mode = mode_native_to_git(buf->st_mode);
3939+ return rc;
4040+}
4141+4242+int git_lstat(const char *path, struct stat *buf)
4343+{
4444+ int rc = lstat(path, buf);
4545+ if (rc == 0)
4646+ buf->st_mode = mode_native_to_git(buf->st_mode);
4747+ return rc;
4848+}
+23
configure.ac
···873873 SNPRINTF_RETURNS_BOGUS=
874874fi
875875GIT_CONF_SUBST([SNPRINTF_RETURNS_BOGUS])
876876+#
877877+# Define NEEDS_MODE_TRANSLATION if your OS strays from the typical file type
878878+# bits in mode values.
879879+AC_CACHE_CHECK([whether the platform uses typical file type bits],
880880+ [ac_cv_sane_mode_bits], [
881881+AC_EGREP_CPP(yippeeyeswehaveit,
882882+ AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT],
883883+[#if S_IFMT == 0170000 && \
884884+ S_IFREG == 0100000 && S_IFDIR == 0040000 && S_IFLNK == 0120000 && \
885885+ S_IFBLK == 0060000 && S_IFCHR == 0020000 && \
886886+ S_IFIFO == 0010000 && S_IFSOCK == 0140000
887887+yippeeyeswehaveit
888888+#endif
889889+]),
890890+ [ac_cv_sane_mode_bits=yes],
891891+ [ac_cv_sane_mode_bits=no])
892892+])
893893+if test $ac_cv_sane_mode_bits = yes; then
894894+ NEEDS_MODE_TRANSLATION=
895895+else
896896+ NEEDS_MODE_TRANSLATION=UnfortunatelyYes
897897+fi
898898+GIT_CONF_SUBST([NEEDS_MODE_TRANSLATION])
876899877900878901## Checks for library functions.