Liu Hao: > There are a few resolution to this at different levels. The most ideal > solution would be providing an `access()` function that behaves > expectedly in gnulib or libiberty, so this recipe can be ported > elsewhere. Modifying GCC source should be considered the least preferred > and last option.
OK, that's what I thought. I've attached a new patch for libiberty, could you please have a quick look at it before I submit it to GCC? It currently only handles F_OK which is the only case which really seems to matter for GCC. I do not know how to check if a file is effectively readable/writeable/executable in the windows api. And it seems reimplementing R_OK and all the other flags would mean effectively rewriting the complete access function. What do you think? Best regards, Johannes --- gcc/gcc.c | 26 +++++++-------- include/libiberty.h | 3 ++ libiberty/Makefile.in | 19 ++++++++--- libiberty/xaccess.c | 74 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 18 deletions(-) create mode 100644 libiberty/xaccess.c diff --git a/gcc/gcc.c b/gcc/gcc.c index 955a08cc8e8..7b4d3cc8326 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -2804,7 +2804,7 @@ access_check (const char *name, int mode) return -1; } - return access (name, mode); + return xaccess (name, mode); } /* Callback for find_a_file. Appends the file name to the directory @@ -2856,12 +2856,12 @@ find_a_file (const struct path_prefix *pprefix, const char *name, int mode, struct file_at_path_info info; #ifdef DEFAULT_ASSEMBLER - if (! strcmp (name, "as") && access (DEFAULT_ASSEMBLER, mode) == 0) + if (! strcmp (name, "as") && xaccess (DEFAULT_ASSEMBLER, mode) == 0) return xstrdup (DEFAULT_ASSEMBLER); #endif #ifdef DEFAULT_LINKER - if (! strcmp (name, "ld") && access (DEFAULT_LINKER, mode) == 0) + if (! strcmp (name, "ld") && xaccess (DEFAULT_LINKER, mode) == 0) return xstrdup (DEFAULT_LINKER); #endif @@ -2869,7 +2869,7 @@ find_a_file (const struct path_prefix *pprefix, const char *name, int mode, if (IS_ABSOLUTE_PATH (name)) { - if (access (name, mode) == 0) + if (xaccess (name, mode) == 0) return xstrdup (name); return NULL; @@ -4528,7 +4528,7 @@ process_command (unsigned int decoded_options_count, long offset; int consumed; #ifdef HAVE_TARGET_OBJECT_SUFFIX - arg = convert_filename (arg, 0, access (arg, F_OK)); + arg = convert_filename (arg, 0, xaccess (arg, F_OK)); #endif /* For LTO static archive support we handle input file specifications that are composed of a filename and @@ -4543,7 +4543,7 @@ process_command (unsigned int decoded_options_count, fname[p - arg] = '\0'; /* Only accept non-stdin and existing FNAME parts, otherwise try with the full name. */ - if (strcmp (fname, "-") == 0 || access (fname, F_OK) < 0) + if (strcmp (fname, "-") == 0 || xaccess (fname, F_OK) < 0) { free (fname); fname = xstrdup (arg); @@ -4552,9 +4552,9 @@ process_command (unsigned int decoded_options_count, else fname = xstrdup (arg); - if (strcmp (fname, "-") != 0 && access (fname, F_OK) < 0) + if (strcmp (fname, "-") != 0 && xaccess (fname, F_OK) < 0) { - bool resp = fname[0] == '@' && access (fname + 1, F_OK) < 0; + bool resp = fname[0] == '@' && xaccess (fname + 1, F_OK) < 0; error ("%s: %m", fname + resp); } else @@ -5383,7 +5383,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) if ((!save_temps_flag) && (stat (HOST_BIT_BUCKET, &st) == 0) && (!S_ISDIR (st.st_mode)) - && (access (HOST_BIT_BUCKET, W_OK) == 0)) + && (xaccess (HOST_BIT_BUCKET, W_OK) == 0)) { obstack_grow (&obstack, HOST_BIT_BUCKET, strlen (HOST_BIT_BUCKET)); @@ -7545,7 +7545,7 @@ driver::set_up_specs () const strcpy (specs_file, standard_exec_prefix); strcat (specs_file, spec_machine_suffix); strcat (specs_file, "specs"); - if (access (specs_file, R_OK) == 0) + if (xaccess (specs_file, R_OK) == 0) read_specs (specs_file, true, false); /* Process any configure-time defaults specified for the command line @@ -7865,7 +7865,7 @@ driver::maybe_print_and_exit () const if (ld == NULL) # endif ld = concat (DEFAULT_LINKER, use_ld, NULL); - if (access (ld, X_OK) == 0) + if (xaccess (ld, X_OK) == 0) { printf ("%s\n", ld); return (0); @@ -9309,7 +9309,7 @@ static const char * if_exists_spec_function (int argc, const char **argv) { /* Must have only one argument. */ - if (argc == 1 && IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK)) + if (argc == 1 && IS_ABSOLUTE_PATH (argv[0]) && ! xaccess (argv[0], R_OK)) return argv[0]; return NULL; @@ -9327,7 +9327,7 @@ if_exists_else_spec_function (int argc, const char **argv) if (argc != 2) return NULL; - if (IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK)) + if (IS_ABSOLUTE_PATH (argv[0]) && ! xaccess (argv[0], R_OK)) return argv[0]; return argv[1]; diff --git a/include/libiberty.h b/include/libiberty.h index 0823614c00e..421fdb0e40a 100644 --- a/include/libiberty.h +++ b/include/libiberty.h @@ -713,6 +713,9 @@ extern void setproctitle (const char *name, ...); /* Increase stack limit if possible. */ extern void stack_limit_increase (unsigned long); +/* Check if file is accessible. */ +extern int xaccess (const char *pathname, int mode); + #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) /* Drastically simplified alloca configurator. If we're using GCC, diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in index ed1b334c361..65229842bdb 100644 --- a/libiberty/Makefile.in +++ b/libiberty/Makefile.in @@ -158,8 +158,8 @@ CFILES = alloca.c argv.c asprintf.c atexit.c \ vasprintf.c vfork.c vfprintf.c vprintf.c vprintf-support.c \ vsnprintf.c vsprintf.c \ waitpid.c \ - xasprintf.c xatexit.c xexit.c xmalloc.c xmemdup.c xstrdup.c \ - xstrerror.c xstrndup.c xvasprintf.c + xaccess.c xasprintf.c xatexit.c xexit.c xmalloc.c xmemdup.c \ + xstrdup.c xstrerror.c xstrndup.c xvasprintf.c # These are always included in the library. The first four are listed # first and by compile time to optimize parallel builds. @@ -191,9 +191,9 @@ REQUIRED_OFILES = \ ./splay-tree.$(objext) ./stack-limit.$(objext) \ ./strerror.$(objext) ./strsignal.$(objext) \ ./timeval-utils.$(objext) ./unlink-if-ordinary.$(objext) \ - ./xasprintf.$(objext) ./xatexit.$(objext) ./xexit.$(objext) \ - ./xmalloc.$(objext) ./xmemdup.$(objext) ./xstrdup.$(objext) \ - ./xstrerror.$(objext) ./xstrndup.$(objext) \ + ./xaccess.$(objext) ./xasprintf.$(objext) ./xatexit.$(objext) \ + ./xexit.$(objext) ./xmalloc.$(objext) ./xmemdup.$(objext) \ + ./xstrdup.$(objext) ./xstrerror.$(objext) ./xstrndup.$(objext) \ ./xvasprintf.$(objext) # These are all the objects that configure may add to the library via @@ -1630,6 +1630,15 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir else true; fi $(COMPILE.c) $(srcdir)/waitpid.c $(OUTPUT_OPTION) +./xaccess.$(objext): $(srcdir)/xaccess.c + if [ x"$(PICFLAG)" != x ]; then \ + $(COMPILE.c) $(PICFLAG) $(srcdir)/xaccess.c -o pic/$@; \ + else true; fi + if [ x"$(NOASANFLAG)" != x ]; then \ + $(COMPILE.c) $(PICFLAG) $(NOASANFLAG) $(srcdir)/xaccess.c -o noasan/$@; \ + else true; fi + $(COMPILE.c) $(srcdir)/xaccess.c $(OUTPUT_OPTION) + ./xasprintf.$(objext): $(srcdir)/xasprintf.c config.h $(INCDIR)/ansidecl.h \ $(INCDIR)/libiberty.h if [ x"$(PICFLAG)" != x ]; then \ diff --git a/libiberty/xaccess.c b/libiberty/xaccess.c new file mode 100644 index 00000000000..e0183963cfa --- /dev/null +++ b/libiberty/xaccess.c @@ -0,0 +1,74 @@ +/* check users permission to access files. + Copyright (C) 1989-2018 Free Software Foundation, Inc. + +This file is part of the libiberty library. +Libiberty is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +Libiberty 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with libiberty; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ + +/* + +@deftypefn Replacement int xaccess (const char *pathname, int mode); + +Check whether the calling process can access pathname. This usually +directly forwards to @code{access}, but some special cases are handled +manually because of portability issues. + +@end deftypefn + +*/ + +#ifdef _WIN32 +#include <windows.h> +#include <io.h> +#else +#include <unistd.h> +#endif + +int +xaccess (const char *pathname, int mode) +{ + /* Win32: only msvcrt.dll handles nul files, msvcr* does not. */ +#ifdef _WIN32 + if (mode == F_OK) + { + if (GetFileAttributesA(pathname) == INVALID_FILE_ATTRIBUTES) + { + switch (GetLastError()) + { + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + errno = ENOENT; + break; + case ERROR_ACCESS_DENIED: + errno = EACCES; + break; + default: + errno = EINVAL; + } + return -1; + } + else + { + return 0; + } + } + else + { + return access(pathname, mode); + } +#else + return access(pathname, mode); +#endif +} -- 2.19.2 _______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public