From daad4fd542e74d22445a05a5be91761f094d4f27 Mon Sep 17 00:00:00 2001 From: fxcoudert Date: Sun, 23 Oct 2005 20:43:54 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@105824 138bc75d-0d04-0410-961f-82ee72b054a4 --- libgfortran/ChangeLog | 15 ++++++++++ libgfortran/acinclude.m4 | 35 ++++++++++++++++++++++ libgfortran/config.h.in | 3 ++ libgfortran/configure | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ libgfortran/configure.ac | 3 ++ libgfortran/io/io.h | 2 +- libgfortran/io/open.c | 2 +- libgfortran/io/unix.c | 23 ++++++++++++--- 8 files changed, 153 insertions(+), 6 deletions(-) diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 1088c76933e..12bf51a5027 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,5 +1,20 @@ 2005-10-23 Francois-Xavier Coudert + 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 + * 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 dbf25f3c636..a94dafafacb 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 +#include +#include +#include + +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 669bc153166..8d6f6d4b204 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 69ca7b75bc4..b3cc868364c 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 +#include +#include +#include + +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 396deb5fe6a..59354c9e188 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 3cb98f42ede..5e3adbc42d9 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 e1e42ad9370..203964b5dea 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 91a7a474d07..2026a364927 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) -- 2.11.0