intprops tests: avoid build failure with HP-UX cc

2019-09-15 Thread Bruno Haible
Building a test dir on HP-UX 11.31 with HP cc, I'm seeing this build failure:

cpp: "../../gltests/test-intprops.c", line 371: error 4018: Macro param too 
large after substitution - use -H option.
gmake[3]: *** [test-intprops.o] Error 1

There are two ways to fix it:
  (a) Add an option -Wp,-H where  ≥ 65793 to the command line,
  such as -Wp,-H65793.
  (b) Skip this particular line of the test.

It would be time consuming for all users on HP-UX of all packages that use
gnulib, to find out and apply option (a). Therefore option (b) is preferrable.


2019-09-15  Bruno Haible  

intprops tests: Avoid build failure with HP-UX cc.
* tests/test-intprops.c: Disable a check that makes HP cc choke with
"error 4018: Macro param too large after substitution - use -H option.".

diff --git a/tests/test-intprops.c b/tests/test-intprops.c
index be0c6b3..1837f7b 100644
--- a/tests/test-intprops.c
+++ b/tests/test-intprops.c
@@ -368,7 +368,9 @@ main (void)
   CHECK_PRODUCT (INT_MAX, UINT_MAX, unsigned int, true, INT_MAX * UINT_MAX);
   CHECK_PRODUCT (INT_MAX, ULONG_MAX, unsigned long int, true,
  INT_MAX * ULONG_MAX);
+#if !defined __HP_cc
   CHECK_SPRODUCT (INT_MIN, LONG_MAX / INT_MIN - 1, long int, true, LONG_MIN);
+#endif
   CHECK_SPRODUCT (INT_MIN, LONG_MAX / INT_MIN, long int, false, DONTCARE);
   CHECK_PRODUCT (INT_MIN, UINT_MAX, unsigned int, true, INT_MIN * UINT_MAX);
   CHECK_PRODUCT (INT_MIN, ULONG_MAX, unsigned long int, true,




new module 'creat'

2019-09-15 Thread Bruno Haible
The creat() function not only has some of the bugs that open() has
(w.r.t. file names that end in a slash). It also crashes when passed
a mode with executable bits, e.g.
   creat ("file", 0700);
on MSVC 14.

I'm therefore adding a new module that works around both issues.
Tested on AIX 7.1, HP-UX 11.31, Solaris 9.


2019-09-15  Bruno Haible  

open tests: Enhance test.
* tests/test-open.h (test_open): Test the creation of an executable
regular file. Also improve initial cleanup.

creat: New module.
* lib/fcntl.in.h (creat): New declaration.
* lib/creat.c: New file, based on lib/open.c.
* m4/creat.m4: New file.
* m4/open-slash.m4: New file, extracted from m4/open.m4.
* m4/open.m4 (gl_FUNC_OPEN): Move trailing-slash test to open-slash.m4.
Invoke gl_OPEN_TRAILING_SLASH_BUG.
* modules/open (Files): Add m4/open-slash.m4.
* m4/fcntl_h.m4 (gl_FCNTL_H_DEFAULTS): Initialize GNULIB_CREAT,
REPLACE_CREAT.
* modules/fcntl-h (Makefile.am): Substitute GNULIB_CREAT, REPLACE_CREAT.
* modules/creat: New file.
* tests/test-fcntl-h-c++.cc (creat): Check signature.
* doc/posix-functions/creat.texi: Mention the new module.

creat: Add tests.
* tests/test-creat.c: New file, based on tests/test-open.h.
* modules/creat-tests: New file.
>From 9e75623a64a07215f2c7811e0356697d6df10fa2 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Sun, 15 Sep 2019 14:41:57 +0200
Subject: [PATCH 1/3] open tests: Enhance test.

* tests/test-open.h (test_open): Test the creation of an executable
regular file. Also improve initial cleanup.
---
 ChangeLog | 6 ++
 tests/test-open.h | 9 +
 2 files changed, 15 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index c94ebeb..9f97bb0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2019-09-15  Bruno Haible  
 
+	open tests: Enhance test.
+	* tests/test-open.h (test_open): Test the creation of an executable
+	regular file. Also improve initial cleanup.
+
+2019-09-15  Bruno Haible  
+
 	intprops tests: Avoid build failure with HP-UX cc.
 	* tests/test-intprops.c: Disable a check that makes HP cc choke with
 	"error 4018: Macro param too large after substitution - use -H option.".
diff --git a/tests/test-open.h b/tests/test-open.h
index e5c47d2..c0290ee 100644
--- a/tests/test-open.h
+++ b/tests/test-open.h
@@ -37,8 +37,11 @@ static ALWAYS_INLINE int
 test_open (int (*func) (char const *, int, ...), bool print)
 {
   int fd;
+
   /* Remove anything from prior partial run.  */
   unlink (BASE "file");
+  unlink (BASE "e.exe");
+  unlink (BASE "link");
 
   /* Cannot create directory.  */
   errno = 0;
@@ -51,6 +54,11 @@ test_open (int (*func) (char const *, int, ...), bool print)
   ASSERT (0 <= fd);
   ASSERT (close (fd) == 0);
 
+  /* Create an executable regular file.  */
+  fd = func (BASE "e.exe", O_CREAT | O_RDONLY, 0700);
+  ASSERT (0 <= fd);
+  ASSERT (close (fd) == 0);
+
   /* Trailing slash handling.  */
   errno = 0;
   ASSERT (func (BASE "file/", O_RDONLY) == -1);
@@ -98,6 +106,7 @@ test_open (int (*func) (char const *, int, ...), bool print)
 
   /* Cleanup.  */
   ASSERT (unlink (BASE "file") == 0);
+  ASSERT (unlink (BASE "e.exe") == 0);
   ASSERT (unlink (BASE "link") == 0);
 
   return 0;
-- 
2.7.4

>From c5f7c7c69b3b986c49930c1c7ac37c552a3be738 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Sun, 15 Sep 2019 17:41:29 +0200
Subject: [PATCH 2/3] creat: New module.

* lib/fcntl.in.h (creat): New declaration.
* lib/creat.c: New file, based on lib/open.c.
* m4/creat.m4: New file.
* m4/open-slash.m4: New file, extracted from m4/open.m4.
* m4/open.m4 (gl_FUNC_OPEN): Move trailing-slash test to open-slash.m4.
Invoke gl_OPEN_TRAILING_SLASH_BUG.
* modules/open (Files): Add m4/open-slash.m4.
* m4/fcntl_h.m4 (gl_FCNTL_H_DEFAULTS): Initialize GNULIB_CREAT,
REPLACE_CREAT.
* modules/fcntl-h (Makefile.am): Substitute GNULIB_CREAT, REPLACE_CREAT.
* modules/creat: New file.
* tests/test-fcntl-h-c++.cc (creat): Check signature.
* doc/posix-functions/creat.texi: Mention the new module.
---
 ChangeLog  | 17 +
 doc/posix-functions/creat.texi | 17 ++---
 lib/creat.c| 78 ++
 lib/fcntl.in.h | 22 +++-
 m4/creat.m4| 23 +
 m4/fcntl_h.m4  |  4 ++-
 m4/open-slash.m4   | 59 
 m4/open.m4 | 41 +-
 modules/creat  | 29 
 modules/fcntl-h|  2 ++
 modules/open   |  1 +
 tests/test-fcntl-h-c++.cc  |  4 +++
 12 files changed, 250 insertions(+), 47 deletions(-)
 create mode 100644 lib/creat.c
 create mode 100644 m4/creat.m4
 create mode 100644 m4/open-slash.m4
 create mode 100644 modules/creat

diff --git a/ChangeLog b/ChangeLog
index 

Re: make autoconf tests work with -Werror=implicit-function-declaration

2019-09-15 Thread Jim Meyering
On Sat, Sep 14, 2019 at 10:51 AM Bruno Haible  wrote:
> There are indications that future GCC versions may be stricter regarding
> invocations of undeclared functions. [1] Configuring with
>   CC="gcc -Werror=implicit-function-declaration"
> is a way to exercise similar functionality with released GCCs.
>
> So, what I did is
>   1. create a testdir of all of gnulib,
>   2. configure it once with CC="gcc" and once with
>  CC="gcc -Werror=implicit-function-declaration", both with option '-C',
>   3. compare the resulting config.cache files.
>
> I got differences in the cache variables
>   gl_cv_func_ptsname_sets_errno
>   gt_cv_locale_tr_utf8
>
> This patch fixes the issues.
>
> [1] https://lists.gnu.org/archive/html/bug-gettext/2019-09/msg00012.html

Thanks for your constant vigilance and all the proactive work on gnulib.



new module 'access'

2019-09-15 Thread Bruno Haible
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  

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 
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  
 
+	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  
+
 	fcntl-h: Fix compilation error of creat.c on MSVC.
 	* lib/fcntl.in.h: Include  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 000..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 .  */
+
+#include 
+
+/* Specification.  */
+#include 
+
+#include 
+#include 
+
+int
+access (const char *file, int mode)
+{
+  if ((mode & X_OK) != 0)
+mode = (m

Re: [PATCH] findprog-in: Set errno to indicate why NULL was returned.

2019-09-15 Thread Bruno Haible
Hi Paul,

> Without this change it's impossible for a program to show the correct
> error message when the program is found on the path, but is not
> executable.

Good point!

I've committed a slightly different patch, based on yours. While your
patch was fully correct, I have different preferences:

  - You don't need a dependency to the 'errno' module, because
(see doc/posix-headers/errno.texi) it is only needed for more
"advanced" errno values. For the basic ones like ENOENT, EINVAL,
EACCES, etc. no portability problems are known.

  - Since the errno value is a saved one in some cases, but not in
all cases, I prefer a variable name 'failure_errno' to 'saved_errno'.

  - In the specification comment in findprog.h: I avoid explaining the
algorithm that a certain function employs. Only: what are the inputs?
what are the outputs? and only the minimal necessary information about
the inner workings of the function.
It must be possible to describe a function in an abstract way. If I
was led to document the algorithm that a function uses, this would
be a sign that the function is not well designed.


2019-09-15  Paul Smith  
Bruno Haible  

findprog-in: Set errno when the search fails.
* lib/findprog-in.c: Include .
(find_in_given_path): Set errno before returning NULL.
* lib/findprog.h (find_in_given_path): Update comment accordingly.
Define the term "slash".

diff --git a/lib/findprog-in.c b/lib/findprog-in.c
index d601e06..5e90680 100644
--- a/lib/findprog-in.c
+++ b/lib/findprog-in.c
@@ -21,6 +21,7 @@
 /* Specification.  */
 #include "findprog.h"
 
+#include 
 #include 
 #include 
 #include 
@@ -98,6 +99,7 @@ find_in_given_path (const char *progname, const char *path,
   {
 /* Try the various suffixes and see whether one of the files
with such a suffix is actually executable.  */
+int failure_errno;
 size_t i;
 #if defined _WIN32 && !defined __CYGWIN__ /* Native Windows */
 const char *progbasename;
@@ -113,6 +115,7 @@ find_in_given_path (const char *progname, const char *path,
 #endif
 
 /* Try all platform-dependent suffixes.  */
+failure_errno = ENOENT;
 for (i = 0; i < sizeof (suffixes) / sizeof (suffixes[0]); i++)
   {
 const char *suffix = suffixes[i];
@@ -143,10 +146,14 @@ find_in_given_path (const char *progname, const char 
*path,
   return progpathname;
   }
 
+if (errno != ENOENT)
+  failure_errno = errno;
+
 free (progpathname);
   }
   }
 
+errno = failure_errno;
 return NULL;
   }
   }
@@ -158,11 +165,13 @@ find_in_given_path (const char *progname, const char 
*path,
 path = "";
 
   {
+int failure_errno;
 /* Make a copy, to prepare for destructive modifications.  */
 char *path_copy = xstrdup (path);
 char *path_rest;
 char *cp;
 
+failure_errno = ENOENT;
 for (path_rest = path_copy; ; path_rest = cp + 1)
   {
 const char *dir;
@@ -222,6 +231,9 @@ find_in_given_path (const char *progname, const char *path,
 return progpathname;
   }
 
+if (errno != ENOENT)
+  failure_errno = errno;
+
 free (progpathname);
   }
   }
@@ -232,7 +244,8 @@ find_in_given_path (const char *progname, const char *path,
 
 /* Not found in PATH.  */
 free (path_copy);
-  }
 
-  return NULL;
+errno = failure_errno;
+return NULL;
+  }
 }
diff --git a/lib/findprog.h b/lib/findprog.h
index f7b4407..804f02a 100644
--- a/lib/findprog.h
+++ b/lib/findprog.h
@@ -36,19 +36,29 @@ extern "C" {
 extern const char *find_in_path (const char *progname);
 
 /* Looks up a program in the given PATH-like string.
+
The PATH argument consists of a list of directories, separated by ':' or
(on native Windows) by ';'.  An empty PATH element designates the current
directory.  A null PATH is equivalent to an empty PATH, that is, to the
singleton list that contains only the current directory.
+
Determines the pathname that would be called by execlp/execvp of PROGNAME.
- If successful, it returns a pathname containing a slash (either absolute
  or relative to the current directory).  The returned string can be used
  with either execl/execv or execlp/execvp.  It is freshly malloc()ed if it
  is != PROGNAME.
-   - Otherwise, it returns NULL.
+   - Otherwise, it sets errno and returns NULL.
+ Specific errno values include:
+   - ENOENT: means that the program's file was not found.
+   - EACCESS: means that the program's file was found but lacks the
+ execute permissions.
If OPTIMIZE_FOR_EXEC is true, the function sav