From: Bruno Haible Date: Thu, 14 Aug 2025 20:16:23 +0000 (+0200) Subject: lchmod: Use issymlink, issymlinkat. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2a98a9ae33269bf37f1825935959d6dd598eb2be;p=thirdparty%2Fgnulib.git lchmod: Use issymlink, issymlinkat. * lib/lchmod.c (lchmod): Use issymlink instead of readlink and issymlinkat instead of readlinkat. * modules/lchmod (Depends-on): Remove readlink. Add issymlink, issymlinkat. --- diff --git a/ChangeLog b/ChangeLog index b69ff7406c..9df8c9b99b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2025-08-14 Bruno Haible + + lchmod: Use issymlink, issymlinkat. + * lib/lchmod.c (lchmod): Use issymlink instead of readlink and + issymlinkat instead of readlinkat. + * modules/lchmod (Depends-on): Remove readlink. Add issymlink, + issymlinkat. + 2025-08-14 Bruno Haible chown: Avoid a redundant stat() call. diff --git a/lib/lchmod.c b/lib/lchmod.c index aabb15e359..4c44ca8063 100644 --- a/lib/lchmod.c +++ b/lib/lchmod.c @@ -37,8 +37,6 @@ int lchmod (char const *file, mode_t mode) { - char readlink_buf[1]; - #ifdef O_PATH /* Open a file descriptor with O_NOFOLLOW, to make sure we don't follow symbolic links, if /proc is mounted. O_PATH is used to @@ -49,17 +47,20 @@ lchmod (char const *file, mode_t mode) return fd; int err; - if (0 <= readlinkat (fd, "", readlink_buf, sizeof readlink_buf)) - err = EOPNOTSUPP; - else if (errno == EINVAL) - { - static char const fmt[] = "/proc/self/fd/%d"; - char buf[sizeof fmt - sizeof "%d" + INT_BUFSIZE_BOUND (int)]; - sprintf (buf, fmt, fd); - err = chmod (buf, mode) == 0 ? 0 : errno == ENOENT ? -1 : errno; - } - else - err = errno == ENOENT ? -1 : errno; + { + int ret = issymlinkat (fd, ""); + if (ret > 0) + err = EOPNOTSUPP; + else if (ret == 0) + { + static char const fmt[] = "/proc/self/fd/%d"; + char buf[sizeof fmt - sizeof "%d" + INT_BUFSIZE_BOUND (int)]; + sprintf (buf, fmt, fd); + err = chmod (buf, mode) == 0 ? 0 : errno == ENOENT ? -1 : errno; + } + else + err = errno == ENOENT ? -1 : errno; + } close (fd); @@ -83,7 +84,7 @@ lchmod (char const *file, mode_t mode) /* O_PATH + /proc is not supported. */ - if (0 <= readlink (file, readlink_buf, sizeof readlink_buf)) + if (issymlink (file) > 0) { errno = EOPNOTSUPP; return -1; diff --git a/modules/lchmod b/modules/lchmod index c087bfa00c..9caa756d21 100644 --- a/modules/lchmod +++ b/modules/lchmod @@ -6,14 +6,15 @@ lib/lchmod.c m4/lchmod.m4 Depends-on: +sys_stat-h +extensions c99 [test $HAVE_LCHMOD = 0] errno-h [test $HAVE_LCHMOD = 0] -extensions fcntl-h [test $HAVE_LCHMOD = 0] intprops [test $HAVE_LCHMOD = 0] +issymlink [test $HAVE_LCHMOD = 0] +issymlinkat [test $HAVE_LCHMOD = 0] lstat [test $HAVE_LCHMOD = 0] -readlink [test $HAVE_LCHMOD = 0] -sys_stat-h unistd-h [test $HAVE_LCHMOD = 0] configure.ac: