aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2025-05-15 17:24:55 -0700
committerJunio C Hamano <gitster@pobox.com>2025-05-15 17:24:55 -0700
commit1d01042e314c0965845cae1fbcd0bc7e21f1b608 (patch)
tree26008dcd8f00394693d3c7464070afe254bffe04
parent1a8a4971cc6c179c4dd711f4a7f5d7178f4b3ab7 (diff)
parentf47bcc3413a946b2735fce84e66efd47cb7be2d2 (diff)
downloadgit-1d01042e314c0965845cae1fbcd0bc7e21f1b608.tar.xz
Merge branch 'cf/wrapper-bsd-eloop'
The fallback implementation of open_nofollow() depended on open("symlink", O_NOFOLLOW) to set errno to ELOOP, but a few BSD derived systems use different errno, which has been worked around. * cf/wrapper-bsd-eloop: wrapper: NetBSD gives EFTYPE and FreeBSD gives EMFILE where POSIX uses ELOOP
-rw-r--r--wrapper.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/wrapper.c b/wrapper.c
index 3c79778055..2f00d2ac87 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -737,7 +737,26 @@ int is_empty_or_missing_file(const char *filename)
int open_nofollow(const char *path, int flags)
{
#ifdef O_NOFOLLOW
- return open(path, flags | O_NOFOLLOW);
+ int ret = open(path, flags | O_NOFOLLOW);
+ /*
+ * NetBSD sets errno to EFTYPE when path is a symlink. The only other
+ * time this errno occurs when O_REGULAR is used. Since we don't use
+ * it anywhere we can avoid an lstat here. FreeBSD does the same with
+ * EMLINK.
+ */
+# ifdef __NetBSD__
+# define SYMLINK_ERRNO EFTYPE
+# elif defined(__FreeBSD__)
+# define SYMLINK_ERRNO EMLINK
+# endif
+# if SYMLINK_ERRNO
+ if (ret < 0 && errno == SYMLINK_ERRNO) {
+ errno = ELOOP;
+ return -1;
+ }
+# undef SYMLINK_ERRNO
+# endif
+ return ret;
#else
struct stat st;
if (lstat(path, &st) < 0)