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 <br...@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.
>From 265886a27c8bc637b1e1f3e85e68d594bbe5fa2c Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@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 <br...@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 <br...@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
>From 213cd443c2fdae0471e30546755e3cd15fcf7d9d Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@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 <br...@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
>From ccfbc26dce79adcb32bf421ff813247699d70ea5 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@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 <br...@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 <br...@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