]> git.ipfire.org Git - thirdparty/gnulib.git/commitdiff
lchown: Use issymlink.
authorBruno Haible <bruno@clisp.org>
Thu, 14 Aug 2025 19:59:20 +0000 (21:59 +0200)
committerBruno Haible <bruno@clisp.org>
Thu, 14 Aug 2025 22:23:22 +0000 (00:23 +0200)
* lib/lchown.c (lchown): Use issymlink instead of readlink.
* modules/lchown (Depends-on): Remove readlink. Add issymlink.

ChangeLog
lib/lchown.c
modules/lchown

index 4e387893cb277ad9f1ff8d9f450a321733605562..b072f949d724e6595d0aee7e79547d863e739f54 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2025-08-14  Bruno Haible  <bruno@clisp.org>
+
+       lchown: Use issymlink.
+       * lib/lchown.c (lchown): Use issymlink instead of readlink.
+       * modules/lchown (Depends-on): Remove readlink. Add issymlink.
+
 2025-08-14  Bruno Haible  <bruno@clisp.org>
 
        chown: Use issymlink.
index ce7d31730a417c30f85f47bdfac4dabece6d10c5..e5e277101c53ad40f6faf32340912c7089e1558a 100644 (file)
@@ -44,9 +44,7 @@ lchown (const char *file, uid_t uid, gid_t gid)
 {
 # if HAVE_CHOWN
 #  if ! CHOWN_MODIFIES_SYMLINK
-  char readlink_buf[1];
-
-  if (0 <= readlink (file, readlink_buf, sizeof readlink_buf))
+  if (issymlink (file) > 0)
     {
       errno = EOPNOTSUPP;
       return -1;
@@ -79,19 +77,22 @@ rpl_lchown (const char *file, uid_t uid, gid_t gid)
     {
       /* Prefer readlink to lstat+S_ISLNK, to avoid EOVERFLOW issues
          in the common case where FILE is a non-symlink.  */
-      char linkbuf[1];
-      int r = readlink (file, linkbuf, 1);
-      if (r < 0)
-        return errno == EINVAL ? chown (file, uid, gid) : r;
+      int ret = issymlink (file);
+      if (ret < 0)
+        return -1;
+      if (ret == 0)
+        /* FILE is not a symlink.  */
+        return chown (file, uid, gid);
 
       /* Later code can use the status, so get it if possible.  */
-      r = lstat (file, &st);
-      if (r < 0)
-        return r;
-      stat_valid = true;
+      ret = lstat (file, &st);
+      if (ret < 0)
+        return -1;
       /* An easy check: did FILE change from a symlink to a non-symlink?  */
       if (!S_ISLNK (st.st_mode))
         return chown (file, uid, gid);
+
+      stat_valid = true;
     }
 # endif
 
index 45f16d91aa9111f032b5b42a20c682be35722bf2..94ba7a9cddd70fcdaa4c6ebb502f492e62e982b9 100644 (file)
@@ -7,7 +7,7 @@ m4/lchown.m4
 
 Depends-on:
 unistd-h
-readlink        [test $HAVE_LCHOWN = 0 || test $REPLACE_LCHOWN = 1]
+issymlink       [test $HAVE_LCHOWN = 0 || test $REPLACE_LCHOWN = 1]
 chown           [test $HAVE_LCHOWN = 0 || test $REPLACE_LCHOWN = 1]
 errno-h         [test $HAVE_LCHOWN = 0 || test $REPLACE_LCHOWN = 1]
 bool            [test $HAVE_LCHOWN = 0 || test $REPLACE_LCHOWN = 1]