diff options
author | Francois-Xavier Coudert <coudert@clipper.ens.fr> | 2005-10-23 22:43:54 +0200 |
---|---|---|
committer | François-Xavier Coudert <fxcoudert@gcc.gnu.org> | 2005-10-23 20:43:54 +0000 |
commit | ad238e4ff7d574bf58d5345ca050949c866867d3 (patch) | |
tree | 5d5bd3e427e9311346a6f6558c309b3c7348fc9d | |
parent | 5f700e6de038a05c3068dac9199b21bbdc70c2e9 (diff) | |
download | gcc-ad238e4ff7d574bf58d5345ca050949c866867d3.zip gcc-ad238e4ff7d574bf58d5345ca050949c866867d3.tar.gz gcc-ad238e4ff7d574bf58d5345ca050949c866867d3.tar.bz2 |
re PR libfortran/23272 ([mingw32] inquire via filename fails)
PR libfortran/23272
* acinclude.m4 (LIBGFOR_CHECK_WORKING_STAT): New check.
* configure.ac: Use LIBGFOR_CHECK_WORKING_STAT.
* Makefile.in: Regenerate.
* aclocal.m4: Regenerate.
* config.h.in: Regenerate.
* configure: Regenerate.
* io/unix.c (compare_file_filename): Add fallback case for
systems without working stat.
* io/open.c (already_open): Correct call to
compare_file_filename.
* io/io.h: Correct proto for compare_file_filename.
From-SVN: r105824
-rw-r--r-- | libgfortran/ChangeLog | 15 | ||||
-rw-r--r-- | libgfortran/acinclude.m4 | 35 | ||||
-rw-r--r-- | libgfortran/config.h.in | 3 | ||||
-rwxr-xr-x | libgfortran/configure | 76 | ||||
-rw-r--r-- | libgfortran/configure.ac | 3 | ||||
-rw-r--r-- | libgfortran/io/io.h | 2 | ||||
-rw-r--r-- | libgfortran/io/open.c | 2 | ||||
-rw-r--r-- | libgfortran/io/unix.c | 23 |
8 files changed, 153 insertions, 6 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 1088c76..12bf51a 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,5 +1,20 @@ 2005-10-23 Francois-Xavier Coudert <coudert@clipper.ens.fr> + PR libfortran/23272 + * acinclude.m4 (LIBGFOR_CHECK_WORKING_STAT): New check. + * configure.ac: Use LIBGFOR_CHECK_WORKING_STAT. + * Makefile.in: Regenerate. + * configure: Regenerate. + * config.h.in: Regenerate. + * aclocal.m4: Regenerate. + * io/unix.c (compare_file_filename): Add fallback case for + systems without working stat. + * io/open.c (already_open): Correct call to + compare_file_filename. + * io/io.h: Correct proto for compare_file_filename. + +2005-10-23 Francois-Xavier Coudert <coudert@clipper.ens.fr> + * runtime/fpu.c: Add _GNU_SOURCE definition. * config/fpu-glibc.h: Remove __USE_GNU definition. diff --git a/libgfortran/acinclude.m4 b/libgfortran/acinclude.m4 index dbf25f3..a94dafa 100644 --- a/libgfortran/acinclude.m4 +++ b/libgfortran/acinclude.m4 @@ -349,3 +349,38 @@ esac])] if test x"$have_broken_fpclassify" = xyes; then AC_DEFINE(HAVE_BROKEN_FPCLASSIFY, 1, [Define if fpclassify is broken.]) fi]) + +dnl Check whether the st_ino and st_dev stat fields taken together uniquely +dnl identify the file within the system. This is should be true for POSIX +dnl systems; it is known to be false on mingw32. +AC_DEFUN([LIBGFOR_CHECK_WORKING_STAT], [ + AC_CACHE_CHECK([whether the target stat is reliable], + have_working_stat, [ + AC_TRY_RUN([ +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +int main () +{ + FILE *f, *g; + struct stat st1, st2; + + f = fopen ("foo", "w"); + g = fopen ("bar", "w"); + if (stat ("foo", &st1) != 0 || stat ("bar", &st2)) + return 1; + if (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino) + return 1; + fclose(f); + fclose(g); + return 0; +}], have_working_stat=yes, have_working_stat=no, [ +case "${target}" in + *mingw*) have_working_stat=no ;; + *) have_working_stat=yes;; +esac])]) +if test x"$have_working_stat" = xyes; then + AC_DEFINE(HAVE_WORKING_STAT, 1, [Define if target has a reliable stat.]) +fi]) diff --git a/libgfortran/config.h.in b/libgfortran/config.h.in index 669bc15..8d6f6d4 100644 --- a/libgfortran/config.h.in +++ b/libgfortran/config.h.in @@ -600,6 +600,9 @@ /* Define if target can unlink open files. */ #undef HAVE_UNLINK_OPEN_FILE +/* Define if target has a reliable stat. */ +#undef HAVE_WORKING_STAT + /* libm includes y0 */ #undef HAVE_Y0 diff --git a/libgfortran/configure b/libgfortran/configure index 69ca7b7..b3cc868 100755 --- a/libgfortran/configure +++ b/libgfortran/configure @@ -19353,6 +19353,82 @@ _ACEOF fi +# Check whether the system has a working stat() + + echo "$as_me:$LINENO: checking whether the target stat is reliable" >&5 +echo $ECHO_N "checking whether the target stat is reliable... $ECHO_C" >&6 +if test "${have_working_stat+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + if test "$cross_compiling" = yes; then + +case "${target}" in + *mingw*) have_working_stat=no ;; + *) have_working_stat=yes;; +esac +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +int main () +{ + FILE *f, *g; + struct stat st1, st2; + + f = fopen ("foo", "w"); + g = fopen ("bar", "w"); + if (stat ("foo", &st1) != 0 || stat ("bar", &st2)) + return 1; + if (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino) + return 1; + fclose(f); + fclose(g); + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + have_working_stat=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +have_working_stat=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $have_working_stat" >&5 +echo "${ECHO_T}$have_working_stat" >&6 +if test x"$have_working_stat" = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_WORKING_STAT 1 +_ACEOF + +fi + # Fallback in case isfinite is not available. echo "$as_me:$LINENO: checking for finite in -lm" >&5 echo $ECHO_N "checking for finite in -lm... $ECHO_C" >&6 diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac index 396deb5..59354c9 100644 --- a/libgfortran/configure.ac +++ b/libgfortran/configure.ac @@ -337,6 +337,9 @@ LIBGFOR_CHECK_FOR_BROKEN_ISNAN # Check for a fpclassify macro that works on long doubles. LIBGFOR_CHECK_FOR_BROKEN_FPCLASSIFY +# Check whether the system has a working stat() +LIBGFOR_CHECK_WORKING_STAT + # Fallback in case isfinite is not available. AC_CHECK_LIB([m],[finite],[AC_DEFINE([HAVE_FINITE],[1],[libm includes finite])]) diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h index 3cb98f4..5e3adbc 100644 --- a/libgfortran/io/io.h +++ b/libgfortran/io/io.h @@ -450,7 +450,7 @@ internal_proto(output_stream); extern stream *error_stream (void); internal_proto(error_stream); -extern int compare_file_filename (stream *, const char *, int); +extern int compare_file_filename (gfc_unit *, const char *, int); internal_proto(compare_file_filename); extern gfc_unit *find_file (void); diff --git a/libgfortran/io/open.c b/libgfortran/io/open.c index e1e42ad..203964b 100644 --- a/libgfortran/io/open.c +++ b/libgfortran/io/open.c @@ -415,7 +415,7 @@ already_open (gfc_unit * u, unit_flags * flags) /* If the file is connected to something else, close it and open a new unit. */ - if (!compare_file_filename (u->s, ioparm.file, ioparm.file_len)) + if (!compare_file_filename (u, ioparm.file, ioparm.file_len)) { if (close_unit (u)) { diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c index 91a7a47..2026a36 100644 --- a/libgfortran/io/unix.c +++ b/libgfortran/io/unix.c @@ -1287,10 +1287,13 @@ init_error_stream (void) * filename. */ int -compare_file_filename (stream * s, const char *name, int len) +compare_file_filename (gfc_unit *u, const char *name, int len) { char path[PATH_MAX + 1]; - struct stat st1, st2; + struct stat st1; +#ifdef HAVE_WORKING_STAT + struct stat st2; +#endif if (unpack_filename (path, name, len)) return 0; /* Can't be the same */ @@ -1301,9 +1304,14 @@ compare_file_filename (stream * s, const char *name, int len) if (stat (path, &st1) < 0) return 0; - fstat (((unix_stream *) s)->fd, &st2); - +#ifdef HAVE_WORKING_STAT + fstat (((unix_stream *) (u->s))->fd, &st2); return (st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino); +#else + if (len != u->file_len) + return 0; + return (memcmp(path, u->file, len) == 0); +#endif } @@ -1312,15 +1320,22 @@ compare_file_filename (stream * s, const char *name, int len) static gfc_unit * find_file0 (gfc_unit * u, struct stat *st1) { +#ifdef HAVE_WORKING_STAT struct stat st2; +#endif gfc_unit *v; if (u == NULL) return NULL; +#ifdef HAVE_WORKING_STAT if (fstat (((unix_stream *) u->s)->fd, &st2) >= 0 && st1->st_dev == st2.st_dev && st1->st_ino == st2.st_ino) return u; +#else + if (compare_string(u->file_len, u->file, ioparm.file_len, ioparm.file) == 0) + return u; +#endif v = find_file0 (u->left, st1); if (v != NULL) |