# HG changeset patch # User Bruno Haible # Date 1050006171 0 # Node ID f292c9f750518833301df834f1aab0bc4424cf8a # Parent b0c93dea12599e6b309bcf245137a76800b6515b New module 'findprog'. diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2003-04-10 Bruno Haible + + * modules/findprog: New file. + * MODULES.html.sh (func_all_modules): Add it. + 2003-04-04 Bruno Haible * modules/linebreak: New file. diff --git a/MODULES.html.sh b/MODULES.html.sh --- a/MODULES.html.sh +++ b/MODULES.html.sh @@ -1837,13 +1837,13 @@ func_wrap H3 func_echo "$element" - #func_begin_table - #func_module findprog + func_begin_table + func_module findprog #func_module wait-process #func_module execute #func_module pipe #func_module sh-quote - #func_end_table + func_end_table element="Java" element=`printf "%s" "$element" | sed -e "$sed_lt" -e "$sed_gt"` diff --git a/lib/ChangeLog b/lib/ChangeLog --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,8 @@ +2003-04-10 Bruno Haible + + * findprog.h: New file, from GNU gettext. + * findprog.c: New file, from GNU gettext. + 2003-04-05 Jim Meyering Merge changes from Coreutils. diff --git a/lib/findprog.c b/lib/findprog.c new file mode 100644 --- /dev/null +++ b/lib/findprog.c @@ -0,0 +1,118 @@ +/* Locating a program in PATH. + Copyright (C) 2001-2003 Free Software Foundation, Inc. + Written by Bruno Haible , 2001. + + 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 2, 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, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +/* Specification. */ +#include "findprog.h" + +#include +#include +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include "xalloc.h" +#include "pathname.h" + + +const char * +find_in_path (const char *progname) +{ +#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__ + /* Win32, OS/2, DOS */ + /* The searching rules with .COM, .EXE, .BAT, .CMD etc. suffixes are + too complicated. Leave it to the OS. */ + return progname; +#else + /* Unix */ + char *path; + char *dir; + char *cp; + + if (strchr (progname, '/') != NULL) + /* If progname contains a slash, it is either absolute or relative to + the current directory. PATH is not used. */ + return progname; + + path = getenv ("PATH"); + if (path == NULL || *path == '\0') + /* If PATH is not set, the default search path is implementation + dependent. */ + return progname; + + /* Make a copy, to prepare for destructive modifications. */ + path = xstrdup (path); + for (dir = path; ; dir = cp + 1) + { + bool last; + char *progpathname; + + /* Extract next directory in PATH. */ + for (cp = dir; *cp != '\0' && *cp != ':'; cp++) + ; + last = (*cp == '\0'); + *cp = '\0'; + + /* Empty PATH components designate the current directory. */ + if (dir == cp) + dir = "."; + + /* Concatenate dir and progname. */ + progpathname = concatenated_pathname (dir, progname, NULL); + + /* On systems which have the eaccess() system call, let's use it. + On other systems, let's hope that this program is not installed + setuid or setgid, so that it is ok to call access() despite its + design flaw. */ + if (eaccess (progpathname, X_OK) == 0) + { + /* Found! */ + if (strcmp (progpathname, progname) == 0) + { + free (progpathname); + + /* Add the "./" prefix for real, that concatenated_pathname() + optimized away. This avoids a second PATH search when the + caller uses execlp/execvp. */ + progpathname = xmalloc (2 + strlen (progname) + 1); + progpathname[0] = '.'; + progpathname[1] = '/'; + memcpy (progpathname + 2, progname, strlen (progname) + 1); + } + + free (path); + return progpathname; + } + + free (progpathname); + + if (last) + break; + } + + /* Not found in PATH. An error will be signalled at the first call. */ + free (path); + return progname; +#endif +} diff --git a/lib/findprog.h b/lib/findprog.h new file mode 100644 --- /dev/null +++ b/lib/findprog.h @@ -0,0 +1,27 @@ +/* Locating a program in PATH. + Copyright (C) 2001-2003 Free Software Foundation, Inc. + Written by Bruno Haible , 2001. + + 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 2, 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, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* Look up a program in the PATH. + Attempt to determine the pathname that would be called by execlp/execvp + of PROGNAME. If successful, return a pathname containing a slash + (either absolute or relative to the current directory). Otherwise, + return PROGNAME unmodified. + Because of the latter case, callers should use execlp/execvp, not + execl/execv on the returned pathname. + The returned string is freshly malloc()ed if it is != PROGNAME. */ +extern const char *find_in_path (const char *progname); diff --git a/m4/ChangeLog b/m4/ChangeLog --- a/m4/ChangeLog +++ b/m4/ChangeLog @@ -1,3 +1,8 @@ +2003-04-10 Bruno Haible + + * findprog.m4: New file. + * eaccess.m4: New file. + 2003-04-04 Bruno Haible * linebreak.m4: New file. diff --git a/m4/eaccess.m4 b/m4/eaccess.m4 new file mode 100644 --- /dev/null +++ b/m4/eaccess.m4 @@ -0,0 +1,14 @@ +# eaccess.m4 serial 1 +dnl Copyright (C) 2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +AC_DEFUN([gl_FUNC_EACCESS], +[ + AC_CHECK_FUNC(eaccess, , + [AC_DEFINE(eaccess, access, + [Define as 'access' if you don't have the eaccess() function.])]) +]) diff --git a/m4/findprog.m4 b/m4/findprog.m4 new file mode 100644 --- /dev/null +++ b/m4/findprog.m4 @@ -0,0 +1,14 @@ +# findprog.m4 serial 1 +dnl Copyright (C) 2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +AC_DEFUN([gl_FINDPROG], +[ + dnl Prerequisites of lib/findprog.c. + AC_CHECK_HEADERS_ONCE(unistd.h) + AC_REQUIRE([gl_FUNC_EACCESS]) +]) diff --git a/modules/findprog b/modules/findprog new file mode 100644 --- /dev/null +++ b/modules/findprog @@ -0,0 +1,26 @@ +Description: +Locating a program in PATH. + +Files: +lib/findprog.h +lib/findprog.c +m4/findprog.m4 +m4/eaccess.m4 + +Depends-on: +stdbool +xalloc +pathname + +configure.ac: +gl_FINDPROG + +Makefile.am: +lib_SOURCES += findprog.h findprog.c + +Include: +"findprog.h" + +Maintainer: +Bruno Haible +