bug-gnulib@gnu.org mirror (unofficial)
 help / color / mirror / Atom feed
From: Bruno Haible <bruno@clisp.org>
To: bug-gnulib@gnu.org
Cc: Paul Smith <psmith@gnu.org>
Subject: new module 'access'
Date: Sun, 15 Sep 2019 19:11:25 +0200	[thread overview]
Message-ID: <39222032.LW4d9PSQ4A@omega> (raw)
In-Reply-To: <20190914193516.21375-1-psmith@gnu.org>

[-- Attachment #1: Type: text/plain, Size: 1246 bytes --]

Paul Smith wrote:
> * lib/findprog-in.c (find_in_given_path): Save errno if it is not ENOENT

While testing whether 'access' really sets errno on native Windows, I found
that:
  - Yes, it does so.
  - But access() with argument X_OK crashes on MSVC. On mingw, it works only
    because mingw links to an older version of the runtime library than MSVC.

So, I'm adding a new module 'access' that makes access(file,X_OK) work
portably.


2019-09-15  Bruno Haible  <bruno@clisp.org>

	access: New module.
	* lib/unistd.in.h (access): New declaration.
	* lib/access.c: New file.
	* m4/access.m4: New file.
	* m4/unistd_h.m4 (gl_UNISTD_H): Test whether access is declared.
	(gl_UNISTD_H_DEFAULTS): Initialize GNULIB_ACCESS, REPLACE_ACCESS.
	* modules/unistd (Makefile.am): Substitute GNULIB_ACCESS,
	REPLACE_ACCESS.
	* modules/access: New file.
	* tests/test-unistd-c++.cc (access): Check signature.
	* doc/posix-functions/access.texi: Mention the new module.

	access: Add tests.
	* tests/test-access.c: New file.
	* modules/access-tests: New file.

	findprog, findprog-lgpl, findprog-in: Fix crash on MSVC.
	* modules/findprog (Depends-on): Add access.
	* modules/findprog-lgpl (Depends-on): Likewise.
	* modules/findprog-in (Depends-on): Likewise.

[-- Attachment #2: 0001-access-New-module.patch --]
[-- Type: text/x-patch, Size: 9563 bytes --]

From 265886a27c8bc637b1e1f3e85e68d594bbe5fa2c Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 15 Sep 2019 18:56:46 +0200
Subject: [PATCH 1/3] access: New module.

* lib/unistd.in.h (access): New declaration.
* lib/access.c: New file.
* m4/access.m4: New file.
* m4/unistd_h.m4 (gl_UNISTD_H): Test whether access is declared.
(gl_UNISTD_H_DEFAULTS): Initialize GNULIB_ACCESS, REPLACE_ACCESS.
* modules/unistd (Makefile.am): Substitute GNULIB_ACCESS,
REPLACE_ACCESS.
* modules/access: New file.
* tests/test-unistd-c++.cc (access): Check signature.
* doc/posix-functions/access.texi: Mention the new module.
---
 ChangeLog                       | 14 ++++++++++++++
 doc/posix-functions/access.texi |  5 ++++-
 lib/access.c                    | 31 +++++++++++++++++++++++++++++++
 lib/unistd.in.h                 | 22 ++++++++++++++++++++--
 m4/access.m4                    | 16 ++++++++++++++++
 m4/unistd_h.m4                  | 10 ++++++----
 modules/access                  | 28 ++++++++++++++++++++++++++++
 modules/unistd                  |  4 +++-
 tests/test-unistd-c++.cc        |  4 ++++
 9 files changed, 126 insertions(+), 8 deletions(-)
 create mode 100644 lib/access.c
 create mode 100644 m4/access.m4
 create mode 100644 modules/access

diff --git a/ChangeLog b/ChangeLog
index 84d9508..b85c3dd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
 2019-09-15  Bruno Haible  <bruno@clisp.org>
 
+	access: New module.
+	* lib/unistd.in.h (access): New declaration.
+	* lib/access.c: New file.
+	* m4/access.m4: New file.
+	* m4/unistd_h.m4 (gl_UNISTD_H): Test whether access is declared.
+	(gl_UNISTD_H_DEFAULTS): Initialize GNULIB_ACCESS, REPLACE_ACCESS.
+	* modules/unistd (Makefile.am): Substitute GNULIB_ACCESS,
+	REPLACE_ACCESS.
+	* modules/access: New file.
+	* tests/test-unistd-c++.cc (access): Check signature.
+	* doc/posix-functions/access.texi: Mention the new module.
+
+2019-09-15  Bruno Haible  <bruno@clisp.org>
+
 	fcntl-h: Fix compilation error of creat.c on MSVC.
 	* lib/fcntl.in.h: Include <io.h> also when __need_system_fcntl_h is
 	defined.
diff --git a/doc/posix-functions/access.texi b/doc/posix-functions/access.texi
index fe66ae0..d9c5006 100644
--- a/doc/posix-functions/access.texi
+++ b/doc/posix-functions/access.texi
@@ -4,10 +4,13 @@
 
 POSIX specification:@* @url{http://www.opengroup.org/onlinepubs/9699919799/functions/access.html}
 
-Gnulib module: ---
+Gnulib module: access
 
 Portability problems fixed by Gnulib:
 @itemize
+@item
+This function does not support the @code{X_OK} mode on some platforms:
+MSVC 14.
 @end itemize
 
 Portability problems not fixed by Gnulib:
diff --git a/lib/access.c b/lib/access.c
new file mode 100644
index 0000000..210f7f4
--- /dev/null
+++ b/lib/access.c
@@ -0,0 +1,31 @@
+/* Test the access rights of a file.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <unistd.h>
+
+#include <fcntl.h>
+#include <io.h>
+
+int
+access (const char *file, int mode)
+{
+  if ((mode & X_OK) != 0)
+    mode = (mode & ~X_OK) | R_OK;
+  return _access (file, mode);
+}
diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index 032cc93..eaf734d 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -253,10 +253,28 @@ _GL_INLINE_HEADER_BEGIN
 /* Declare overridden functions.  */
 
 
-#if defined GNULIB_POSIXCHECK
+#if @GNULIB_ACCESS@
+# if @REPLACE_ACCESS@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef access
+#   define access rpl_access
+#  endif
+_GL_FUNCDECL_RPL (access, int, (const char *file, int mode)
+                               _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (access, int, (const char *file, int mode));
+# else
+_GL_CXXALIAS_SYS (access, int, (const char *file, int mode));
+# endif
+_GL_CXXALIASWARN (access);
+#elif defined GNULIB_POSIXCHECK
+# undef access
+# if HAVE_RAW_DECL_ACCESS
 /* The access() function is a security risk.  */
-_GL_WARN_ON_USE (access, "the access function is a security risk - "
+_GL_WARN_ON_USE (access, "access does not always support X_OK - "
+                 "use gnulib module access for portability; "
+                 "also, this function is a security risk - "
                  "use the gnulib module faccessat instead");
+# endif
 #endif
 
 
diff --git a/m4/access.m4 b/m4/access.m4
new file mode 100644
index 0000000..a718f81
--- /dev/null
+++ b/m4/access.m4
@@ -0,0 +1,16 @@
+# access.m4 serial 1
+dnl Copyright (C) 2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_ACCESS],
+[
+  AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  dnl On native Windows, access (= _access) does not support the X_OK mode.
+  dnl It works by chance on some versions of mingw.
+  case "$host_os" in
+    mingw*) REPLACE_ACCESS=1 ;;
+  esac
+])
diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4
index a3b3905..18b7140 100644
--- a/m4/unistd_h.m4
+++ b/m4/unistd_h.m4
@@ -1,4 +1,4 @@
-# unistd_h.m4 serial 75
+# unistd_h.m4 serial 76
 dnl Copyright (C) 2006-2019 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -41,9 +41,9 @@ AC_DEFUN([gl_UNISTD_H],
 #  include <io.h>
 # endif
 #endif
-    ]], [chdir chown dup dup2 dup3 environ euidaccess faccessat fchdir fchownat
-    fdatasync fsync ftruncate getcwd getdomainname getdtablesize getgroups
-    gethostname getlogin getlogin_r getpagesize getpass
+    ]], [access chdir chown dup dup2 dup3 environ euidaccess faccessat fchdir
+    fchownat fdatasync fsync ftruncate getcwd getdomainname getdtablesize
+    getgroups gethostname getlogin getlogin_r getpagesize getpass
     getusershell setusershell endusershell
     group_member isatty lchown link linkat lseek pipe pipe2 pread pwrite
     readlink readlinkat rmdir sethostname sleep symlink symlinkat
@@ -61,6 +61,7 @@ AC_DEFUN([gl_UNISTD_MODULE_INDICATOR],
 
 AC_DEFUN([gl_UNISTD_H_DEFAULTS],
 [
+  GNULIB_ACCESS=0;               AC_SUBST([GNULIB_ACCESS])
   GNULIB_CHDIR=0;                AC_SUBST([GNULIB_CHDIR])
   GNULIB_CHOWN=0;                AC_SUBST([GNULIB_CHOWN])
   GNULIB_CLOSE=0;                AC_SUBST([GNULIB_CLOSE])
@@ -159,6 +160,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
   HAVE_DECL_TTYNAME_R=1;  AC_SUBST([HAVE_DECL_TTYNAME_R])
   HAVE_OS_H=0;            AC_SUBST([HAVE_OS_H])
   HAVE_SYS_PARAM_H=0;     AC_SUBST([HAVE_SYS_PARAM_H])
+  REPLACE_ACCESS=0;       AC_SUBST([REPLACE_ACCESS])
   REPLACE_CHOWN=0;        AC_SUBST([REPLACE_CHOWN])
   REPLACE_CLOSE=0;        AC_SUBST([REPLACE_CLOSE])
   REPLACE_DUP=0;          AC_SUBST([REPLACE_DUP])
diff --git a/modules/access b/modules/access
new file mode 100644
index 0000000..7434e02
--- /dev/null
+++ b/modules/access
@@ -0,0 +1,28 @@
+Description:
+access() function: test the access rights of a file.
+
+Files:
+lib/access.c
+m4/access.m4
+
+Depends-on:
+unistd
+fcntl
+
+configure.ac:
+gl_FUNC_ACCESS
+if test $REPLACE_ACCESS = 1; then
+  AC_LIBOBJ([access])
+fi
+gl_UNISTD_MODULE_INDICATOR([access])
+
+Makefile.am:
+
+Include:
+<unistd.h>
+
+License:
+LGPLv2+
+
+Maintainer:
+all
diff --git a/modules/unistd b/modules/unistd
index e29c1ad..b68029d 100644
--- a/modules/unistd
+++ b/modules/unistd
@@ -36,6 +36,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
 	      -e 's|@''NEXT_UNISTD_H''@|$(NEXT_UNISTD_H)|g' \
 	      -e 's|@''WINDOWS_64_BIT_OFF_T''@|$(WINDOWS_64_BIT_OFF_T)|g' \
+	      -e 's/@''GNULIB_ACCESS''@/$(GNULIB_ACCESS)/g' \
 	      -e 's/@''GNULIB_CHDIR''@/$(GNULIB_CHDIR)/g' \
 	      -e 's/@''GNULIB_CHOWN''@/$(GNULIB_CHOWN)/g' \
 	      -e 's/@''GNULIB_CLOSE''@/$(GNULIB_CLOSE)/g' \
@@ -135,7 +136,8 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
 	      -e 's|@''HAVE_OS_H''@|$(HAVE_OS_H)|g' \
 	      -e 's|@''HAVE_SYS_PARAM_H''@|$(HAVE_SYS_PARAM_H)|g' \
 	  | \
-	  sed -e 's|@''REPLACE_CHOWN''@|$(REPLACE_CHOWN)|g' \
+	  sed -e 's|@''REPLACE_ACCESS''@|$(REPLACE_ACCESS)|g' \
+	      -e 's|@''REPLACE_CHOWN''@|$(REPLACE_CHOWN)|g' \
 	      -e 's|@''REPLACE_CLOSE''@|$(REPLACE_CLOSE)|g' \
 	      -e 's|@''REPLACE_DUP''@|$(REPLACE_DUP)|g' \
 	      -e 's|@''REPLACE_DUP2''@|$(REPLACE_DUP2)|g' \
diff --git a/tests/test-unistd-c++.cc b/tests/test-unistd-c++.cc
index e6a6952..8ba7a04 100644
--- a/tests/test-unistd-c++.cc
+++ b/tests/test-unistd-c++.cc
@@ -24,6 +24,10 @@
 #include "signature.h"
 
 
+#if GNULIB_TEST_ACCESS
+SIGNATURE_CHECK (GNULIB_NAMESPACE::access, int, (const char *, int));
+#endif
+
 #if GNULIB_TEST_CHDIR
 SIGNATURE_CHECK (GNULIB_NAMESPACE::chdir, int, (const char *));
 #endif
-- 
2.7.4


[-- Attachment #3: 0002-access-Add-tests.patch --]
[-- Type: text/x-patch, Size: 3477 bytes --]

From 213cd443c2fdae0471e30546755e3cd15fcf7d9d Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 15 Sep 2019 18:58:42 +0200
Subject: [PATCH 2/3] access: Add tests.

* tests/test-access.c: New file.
* modules/access-tests: New file.
---
 ChangeLog            |  4 +++
 modules/access-tests | 13 +++++++++
 tests/test-access.c  | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 97 insertions(+)
 create mode 100644 modules/access-tests
 create mode 100644 tests/test-access.c

diff --git a/ChangeLog b/ChangeLog
index b85c3dd..394dcd5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2019-09-15  Bruno Haible  <bruno@clisp.org>
 
+	access: Add tests.
+	* tests/test-access.c: New file.
+	* modules/access-tests: New file.
+
 	access: New module.
 	* lib/unistd.in.h (access): New declaration.
 	* lib/access.c: New file.
diff --git a/modules/access-tests b/modules/access-tests
new file mode 100644
index 0000000..082aeb5
--- /dev/null
+++ b/modules/access-tests
@@ -0,0 +1,13 @@
+Files:
+tests/test-access.c
+tests/signature.h
+tests/macros.h
+
+Depends-on:
+creat
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-access
+check_PROGRAMS += test-access
diff --git a/tests/test-access.c b/tests/test-access.c
new file mode 100644
index 0000000..7af7f9a
--- /dev/null
+++ b/tests/test-access.c
@@ -0,0 +1,80 @@
+/* Tests of access.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (access, int, (const char *, int));
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include "macros.h"
+
+#define BASE "test-access.t"
+
+int
+main ()
+{
+  /* Remove anything from prior partial run.  */
+  unlink (BASE "f");
+  unlink (BASE "f1");
+  unlink (BASE "f2");
+
+  {
+    errno = 0;
+    ASSERT (access (BASE "f", R_OK) == -1);
+    ASSERT (errno == ENOENT);
+
+    errno = 0;
+    ASSERT (access (BASE "f", W_OK) == -1);
+    ASSERT (errno == ENOENT);
+
+    errno = 0;
+    ASSERT (access (BASE "f", X_OK) == -1);
+    ASSERT (errno == ENOENT);
+  }
+  {
+    ASSERT (close (creat (BASE "f1", 0700)) == 0);
+
+    ASSERT (access (BASE "f1", R_OK) == 0);
+    ASSERT (access (BASE "f1", W_OK) == 0);
+    ASSERT (access (BASE "f1", X_OK) == 0);
+  }
+  {
+    ASSERT (close (creat (BASE "f2", 0600)) == 0);
+    ASSERT (chmod (BASE "f2", 0400) == 0);
+
+    ASSERT (access (BASE "f2", R_OK) == 0);
+
+    errno = 0;
+    ASSERT (access (BASE "f2", W_OK) == -1);
+    ASSERT (errno == EACCES);
+
+#if defined _WIN32 && !defined __CYGWIN__
+    /* X_OK works like R_OK.  */
+    ASSERT (access (BASE "f2", X_OK) == 0);
+#else
+    errno = 0;
+    ASSERT (access (BASE "f2", X_OK) == -1);
+    ASSERT (errno == EACCES);
+#endif
+  }
+
+  return 0;
+}
-- 
2.7.4


[-- Attachment #4: 0003-findprog-findprog-lgpl-findprog-in-Fix-crash-on-MSVC.patch --]
[-- Type: text/x-patch, Size: 1740 bytes --]

From ccfbc26dce79adcb32bf421ff813247699d70ea5 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 15 Sep 2019 19:00:51 +0200
Subject: [PATCH 3/3] findprog, findprog-lgpl, findprog-in: Fix crash on MSVC.

* modules/findprog (Depends-on): Add access.
* modules/findprog-lgpl (Depends-on): Likewise.
* modules/findprog-in (Depends-on): Likewise.
---
 ChangeLog             | 7 +++++++
 modules/findprog      | 1 +
 modules/findprog-in   | 1 +
 modules/findprog-lgpl | 1 +
 4 files changed, 10 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 394dcd5..7d2eb3a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2019-09-15  Bruno Haible  <bruno@clisp.org>
 
+	findprog, findprog-lgpl, findprog-in: Fix crash on MSVC.
+	* modules/findprog (Depends-on): Add access.
+	* modules/findprog-lgpl (Depends-on): Likewise.
+	* modules/findprog-in (Depends-on): Likewise.
+
+2019-09-15  Bruno Haible  <bruno@clisp.org>
+
 	access: Add tests.
 	* tests/test-access.c: New file.
 	* modules/access-tests: New file.
diff --git a/modules/findprog b/modules/findprog
index c849d66..d48158b 100644
--- a/modules/findprog
+++ b/modules/findprog
@@ -11,6 +11,7 @@ Depends-on:
 stdbool
 xalloc
 xconcat-filename
+access
 unistd
 
 configure.ac:
diff --git a/modules/findprog-in b/modules/findprog-in
index ce7faa5..971366b 100644
--- a/modules/findprog-in
+++ b/modules/findprog-in
@@ -12,6 +12,7 @@ stdbool
 filename
 xalloc
 xconcat-filename
+access
 unistd
 
 configure.ac:
diff --git a/modules/findprog-lgpl b/modules/findprog-lgpl
index 63c78d0..477eccb 100644
--- a/modules/findprog-lgpl
+++ b/modules/findprog-lgpl
@@ -12,6 +12,7 @@ Depends-on:
 stdbool
 strdup
 concat-filename
+access
 unistd
 
 configure.ac:
-- 
2.7.4


  parent reply	other threads:[~2019-09-15 17:11 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-14 19:35 [PATCH] findprog-in: Set errno to indicate why NULL was returned Paul Smith
2019-09-14 19:38 ` Paul Smith
2019-09-15 17:11 ` Bruno Haible [this message]
2019-09-16 15:22   ` new module 'access' Eli Zaretskii
2019-09-16 22:45     ` Bruno Haible
2019-09-17  6:15       ` Eli Zaretskii
2019-09-28 12:06         ` Bruno Haible
2019-09-28 12:17           ` Eli Zaretskii
2019-09-28 13:29             ` Bruno Haible
2019-09-28 13:54               ` Eli Zaretskii
2019-09-15 17:58 ` [PATCH] findprog-in: Set errno to indicate why NULL was returned Bruno Haible
2019-09-16 15:18   ` Eli Zaretskii
2019-09-28 11:48     ` Bruno Haible

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://lists.gnu.org/mailman/listinfo/bug-gnulib

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=39222032.LW4d9PSQ4A@omega \
    --to=bruno@clisp.org \
    --cc=bug-gnulib@gnu.org \
    --cc=psmith@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).