OSDN Git Service

PR libfortran/23272
authorfxcoudert <fxcoudert@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 23 Oct 2005 20:43:54 +0000 (20:43 +0000)
committerfxcoudert <fxcoudert@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 23 Oct 2005 20:43:54 +0000 (20:43 +0000)
* 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
libgfortran/acinclude.m4
libgfortran/config.h.in
libgfortran/configure
libgfortran/configure.ac
libgfortran/io/io.h
libgfortran/io/open.c
libgfortran/io/unix.c

index 1088c76..12bf51a 100644 (file)
@@ -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.
 
index dbf25f3..a94dafa 100644 (file)
@@ -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])
index 669bc15..8d6f6d4 100644 (file)
 /* 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
 
index 69ca7b7..b3cc868 100755 (executable)
@@ -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
index 396deb5..59354c9 100644 (file)
@@ -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])])
 
index 3cb98f4..5e3adbc 100644 (file)
@@ -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);
index e1e42ad..203964b 100644 (file)
@@ -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))
        {
index 91a7a47..2026a36 100644 (file)
@@ -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)