Thanks for reporting those problems. I installed the attached, which fixed things for me on GNU/Linux and AIX. I think it should also put a dent into the problems you reported on MS-Windows, though I can't easily test this.

From f34fd6a906b6dafe4a5fba13a622b12358510bef Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Sun, 19 Jun 2022 23:29:07 -0500
Subject: [PATCH 1/2] fchmodat: pacify gcc -Wunused-variable

Problem reported by Bruno Haible in:
https://lists.gnu.org/r/bug-gnulib/2022-06/msg00075.html
* lib/fchmodat.c (fchmodat): Remove unused local.
---
 ChangeLog      | 7 +++++++
 lib/fchmodat.c | 1 -
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index c9975f436b..a815ca62cd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2022-06-19  Paul Eggert  <egg...@cs.ucla.edu>
+
+	fchmodat: pacify gcc -Wunused-variable
+	Problem reported by Bruno Haible in:
+	https://lists.gnu.org/r/bug-gnulib/2022-06/msg00075.html
+	* lib/fchmodat.c (fchmodat): Remove unused local.
+
 2022-06-19  Bruno Haible  <br...@clisp.org>
 
 	getlogin, getlogin_r tests: Really avoid test failure.
diff --git a/lib/fchmodat.c b/lib/fchmodat.c
index 8ed4cb7398..164e2c4a95 100644
--- a/lib/fchmodat.c
+++ b/lib/fchmodat.c
@@ -96,7 +96,6 @@ fchmodat (int dir, char const *file, mode_t mode, int flags)
         return fd;
 
       int err;
-      char buf[1];
       if (0 <= readlinkat (fd, "", readlink_buf, sizeof readlink_buf))
         err = EOPNOTSUPP;
       else if (errno == EINVAL)
-- 
2.36.1

From c0d456de4dd6a71d56677e5ef21016348e87549e Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Sun, 19 Jun 2022 23:30:01 -0500
Subject: [PATCH 2/2] lchmod: port back to AIX 7.2

Problem reported by Bruno Haible in:
https://lists.gnu.org/r/bug-gnulib/2022-06/msg00075.html
* lib/lchmod.c: Include string.h, for strlen.
(lchmod): Do not depend on HAVE_READLINK since we now depend on
the readlink module.  Check for AIX 7.2 bug.
* m4/lchmod.m4 (gl_PREREQ_LCHMOD): Do not check for readlink
since we now depend on the readlink module.
* modules/lchmod (Depends-on): Depend on readlink.
---
 ChangeLog                       | 10 ++++++++++
 doc/glibc-functions/lchmod.texi |  4 ++++
 doc/posix-functions/chmod.texi  |  4 ++++
 lib/lchmod.c                    | 20 ++++++++++++++++----
 m4/lchmod.m4                    |  3 +--
 modules/lchmod                  |  1 +
 6 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a815ca62cd..0a6434ad88 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2022-06-19  Paul Eggert  <egg...@cs.ucla.edu>
 
+	lchmod: port back to AIX 7.2
+	Problem reported by Bruno Haible in:
+	https://lists.gnu.org/r/bug-gnulib/2022-06/msg00075.html
+	* lib/lchmod.c: Include string.h, for strlen.
+	(lchmod): Do not depend on HAVE_READLINK since we now depend on
+	the readlink module.  Check for AIX 7.2 bug.
+	* m4/lchmod.m4 (gl_PREREQ_LCHMOD): Do not check for readlink
+	since we now depend on the readlink module.
+	* modules/lchmod (Depends-on): Depend on readlink.
+
 	fchmodat: pacify gcc -Wunused-variable
 	Problem reported by Bruno Haible in:
 	https://lists.gnu.org/r/bug-gnulib/2022-06/msg00075.html
diff --git a/doc/glibc-functions/lchmod.texi b/doc/glibc-functions/lchmod.texi
index 8d4fd5b890..df535eab34 100644
--- a/doc/glibc-functions/lchmod.texi
+++ b/doc/glibc-functions/lchmod.texi
@@ -16,6 +16,10 @@ HP-UX 11.31.
 This function always fails with @code{errno} set to @code{ENOSYS},
 even when the file is not a symbolic link:
 GNU/Linux with glibc 2.31.
+@item
+This function does not fail when the file name argument ends in a slash
+and (without the slash) names a non-directory, on some platforms:
+AIX 7.2.
 @end itemize
 
 Portability problems not fixed by Gnulib:
diff --git a/doc/posix-functions/chmod.texi b/doc/posix-functions/chmod.texi
index b425c680be..90175fd7b9 100644
--- a/doc/posix-functions/chmod.texi
+++ b/doc/posix-functions/chmod.texi
@@ -12,4 +12,8 @@ Portability problems fixed by Gnulib:
 
 Portability problems not fixed by Gnulib:
 @itemize
+@item
+This function does not fail when the file name argument ends in a slash
+and (without the slash) names a non-directory, on some platforms:
+AIX 7.2.
 @end itemize
diff --git a/lib/lchmod.c b/lib/lchmod.c
index f21bf7f652..9802098421 100644
--- a/lib/lchmod.c
+++ b/lib/lchmod.c
@@ -25,6 +25,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
+#include <string.h>
 #include <unistd.h>
 
 #ifdef __osf__
@@ -45,10 +46,9 @@
 int
 lchmod (char const *file, mode_t mode)
 {
-#if HAVE_READLINK
   char readlink_buf[1];
 
-# ifdef O_PATH
+#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
      avoid a failure if the file is not readable.
@@ -75,7 +75,20 @@ lchmod (char const *file, mode_t mode)
   errno = err;
   if (0 <= err)
     return err == 0 ? 0 : -1;
-# endif
+#endif
+
+  size_t len = strlen (file);
+  if (len && file[len - 1] == '/')
+    {
+      struct stat st;
+      if (lstat (file, &st) < 0)
+        return -1;
+      if (!S_ISDIR (st.st_mode))
+        {
+          errno = ENOTDIR;
+          return -1;
+        }
+    }
 
   /* O_PATH + /proc is not supported.  */
 
@@ -84,7 +97,6 @@ lchmod (char const *file, mode_t mode)
       errno = EOPNOTSUPP;
       return -1;
     }
-#endif
 
   /* Fall back on chmod, despite a possible race.  */
   return chmod (file, mode);
diff --git a/m4/lchmod.m4 b/m4/lchmod.m4
index bfc925fbe4..cd43beed85 100644
--- a/m4/lchmod.m4
+++ b/m4/lchmod.m4
@@ -1,4 +1,4 @@
-#serial 9
+#serial 10
 
 dnl Copyright (C) 2005-2006, 2008-2022 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
@@ -24,6 +24,5 @@ AC_DEFUN([gl_FUNC_LCHMOD],
 # Prerequisites of lib/lchmod.c.
 AC_DEFUN([gl_PREREQ_LCHMOD],
 [
-  AC_CHECK_FUNCS_ONCE([readlink])
   :
 ])
diff --git a/modules/lchmod b/modules/lchmod
index cce1500af7..8625076c82 100644
--- a/modules/lchmod
+++ b/modules/lchmod
@@ -12,6 +12,7 @@ extensions
 fcntl-h       [test $HAVE_LCHMOD = 0]
 intprops      [test $HAVE_LCHMOD = 0]
 lstat         [test $HAVE_LCHMOD = 0]
+readlink      [test $HAVE_LCHMOD = 0]
 sys_stat
 unistd        [test $HAVE_LCHMOD = 0]
 
-- 
2.36.1

Reply via email to