Re: [PATCH] findprog: Support searching in a specified path string

2019-09-14 Thread Bruno Haible
Hi Paul,

> note that
> on Windows, which is the only place this matters, so far,  IIRC it is
> illegal to use "prog.exe.exe" so if an extension is already provided
> the system won't search again

Indeed, the native Windows execlp() function behaves like this:
  - If the caller specifies "prog.exe.exe" or "prog.foo.exe" and
that file will be exists, it will be found and executed.
  - If the caller specifies "prog.exe" or "prog.foo" but that file
does not exist, the search will NOT extend to "prog.exe.exe" or
"prog.foo.exe", respectively.

I'm updating the code (patch below).

> I actually don't see any need for this optimization, especially
> compared to the added complexity of the API and docs: the suffix check
> needs to be done somewhere after all.

But on platforms like Cygwin, it would be done twice.


2019-09-14  Bruno Haible  

findprog-in: Better mimic the system on native Windows.
Reported by Paul Smith .
* lib/findprog-in.c (find_in_given_path): On native Windows, don't try
non-empty suffixes when the file name already contains a '.'.

diff --git a/lib/findprog-in.c b/lib/findprog-in.c
index 99b3c31..d601e06 100644
--- a/lib/findprog-in.c
+++ b/lib/findprog-in.c
@@ -118,8 +118,9 @@ find_in_given_path (const char *progname, const char *path,
 const char *suffix = suffixes[i];
 
 #if defined _WIN32 && !defined __CYGWIN__ /* Native Windows */
-/* File names without a '.' are not considered executable.  */
-if (*suffix != '\0' || strchr (progbasename, '.') != NULL)
+/* File names without a '.' are not considered executable, and
+   for file names with a '.' no additional suffix is tried.  */
+if ((*suffix != '\0') != (strchr (progbasename, '.') != NULL))
 #endif
   {
 /* Concatenate progname and suffix.  */
@@ -185,8 +186,9 @@ find_in_given_path (const char *progname, const char *path,
 const char *suffix = suffixes[i];
 
 #if defined _WIN32 && !defined __CYGWIN__ /* Native Windows */
-/* File names without a '.' are not considered executable.  */
-if (*suffix != '\0' || strchr (progname, '.') != NULL)
+/* File names without a '.' are not considered executable, and
+   for file names with a '.' no additional suffix is tried.  */
+if ((*suffix != '\0') != (strchr (progname, '.') != NULL))
 #endif
   {
 /* Concatenate dir, progname, and suffix.  */




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

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


2019-09-14  Bruno Haible  

Make autoconf tests work with -Werror=implicit-function-declaration.
* m4/locale-tr.m4 (gt_LOCALE_TR_UTF8): Include , for
towupper() declaration.
* m4/ptsname.m4 (gl_FUNC_PTSNAME): Include , for ptsname()
declaration.

diff --git a/m4/locale-tr.m4 b/m4/locale-tr.m4
index aeb2419..4c413f0 100644
--- a/m4/locale-tr.m4
+++ b/m4/locale-tr.m4
@@ -1,4 +1,4 @@
-# locale-tr.m4 serial 11
+# locale-tr.m4 serial 12
 dnl Copyright (C) 2003, 2005-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,
@@ -21,6 +21,7 @@ changequote(,)dnl
 #endif
 #include 
 #include 
+#include 
 struct tm t;
 char buf[16];
 int main () {
diff --git a/m4/ptsname.m4 b/m4/ptsname.m4
index 5033d90..04bfd3b 100644
--- a/m4/ptsname.m4
+++ b/m4/ptsname.m4
@@ -1,4 +1,4 @@
-# ptsname.m4 serial 7
+# ptsname.m4 serial 8
 dnl Copyright (C) 2010-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,
@@ -19,10 +19,12 @@ AC_DEFUN([gl_FUNC_PTSNAME],
 AC_CACHE_CHECK([whether ptsname sets errno on failure],
   [gl_cv_func_ptsname_sets_errno],
   [AC_RUN_IFELSE(
- [AC_LANG_PROGRAM([[#include 
-  ]], [[
-  return ptsname (-1) || !errno;
-   ]])],
+ [AC_LANG_PROGRAM([[
+  #include 
+  #include 
+]], [[
+  return ptsname (-1) || !errno;
+]])],
  [gl_cv_func_ptsname_sets_errno=yes],
  [gl_cv_func_ptsname_sets_errno=no],
  [case "$host_os" in




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

2019-09-14 Thread Paul Smith
Set errno to either ENOENT if the program was not found, or another
error if a program was found but was no suitable (i.e., EACCES).

* modules/findprog: Depend on errno.
* lib/findprog-in.c (find_in_given_path): Save errno if it is not ENOENT
and reset errno before returning NULL.
* lib/findprog.h (find_in_given_path): Update the documentation.
---
 lib/findprog-in.c   |  9 +
 lib/findprog.h  | 20 
 modules/findprog-in |  1 +
 3 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/lib/findprog-in.c b/lib/findprog-in.c
index d601e060d..8ea03f8f7 100644
--- a/lib/findprog-in.c
+++ b/lib/findprog-in.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "filename.h"
@@ -74,6 +75,8 @@ const char *
 find_in_given_path (const char *progname, const char *path,
 bool optimize_for_exec)
 {
+  int saved_errno = ENOENT;
+
   {
 bool has_slash = false;
 {
@@ -142,11 +145,14 @@ find_in_given_path (const char *progname, const char 
*path,
 else
   return progpathname;
   }
+else if (errno != ENOENT)
+  saved_errno = errno;
 
 free (progpathname);
   }
   }
 
+errno = saved_errno;
 return NULL;
   }
   }
@@ -221,6 +227,8 @@ find_in_given_path (const char *progname, const char *path,
 free (path_copy);
 return progpathname;
   }
+else if (errno != ENOENT)
+  saved_errno = errno;
 
 free (progpathname);
   }
@@ -234,5 +242,6 @@ find_in_given_path (const char *progname, const char *path,
 free (path_copy);
   }
 
+  errno = saved_errno;
   return NULL;
 }
diff --git a/lib/findprog.h b/lib/findprog.h
index f7b44071f..b1b6caa5f 100644
--- a/lib/findprog.h
+++ b/lib/findprog.h
@@ -41,14 +41,18 @@ extern const char *find_in_path (const char *progname);
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.
-   If OPTIMIZE_FOR_EXEC is true, the function saves some work, under the
-   assumption that the resulting pathname will not be accessed directly,
-   only through execl/execv or execlp/execvp.  */
+   On systems which support executable suffixes these are checked, if PROGNAME
+   does not already contain a suffix.
+   Returns either PROGNAME, or a freshly malloc()ed string, or NULL.  If NULL
+   is returned then errno is set (ENOENT, EACCES, etc.)
+   If PROGNAME contains a slash ('/' on POSIX; '/' or '\' on Windows) then:
+   - If OPTIMIZE_FOR_EXEC is true returns PROGNAME without checking suffixes
+ or existence under the assumption that the resulting pathname will be
+ used with execl/execv/execlp/execvp.
+   - Else if PROGNAME refers an executable program it is returned.
+   - Else NULL is returned and errno is set.
+   Otherwise PATH is searched and the pathname is returned if found, or
+   returns NULL and errno is set.  */
 extern const char *find_in_given_path (const char *progname, const char *path,
bool optimize_for_exec);
 
diff --git a/modules/findprog-in b/modules/findprog-in
index ce7faa50e..d38e6f2be 100644
--- a/modules/findprog-in
+++ b/modules/findprog-in
@@ -9,6 +9,7 @@ m4/eaccess.m4
 
 Depends-on:
 stdbool
+errno
 filename
 xalloc
 xconcat-filename
-- 
2.18.0




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

2019-09-14 Thread Paul Smith
On Sat, 2019-09-14 at 15:35 -0400, Paul Smith wrote:
> Set errno to either ENOENT if the program was not found, or another
> error if a program was found but was no suitable (i.e., EACCES).

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.