This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [gfortran] patch for unlink on open files
- From: FX Coudert <fxcoudert at gmail dot com>
- To: Steve Kargl <sgk at troutmask dot apl dot washington dot edu>
- Cc: gfortran <fortran at gcc dot gnu dot org>, patch <gcc-patches at gcc dot gnu dot org>
- Date: Sun, 07 Aug 2005 19:59:47 +0200
- Subject: Re: [gfortran] patch for unlink on open files
- References: <42F5F0A8.6030304@gmail.com> <20050807161934.GB17537@troutmask.apl.washington.edu>
I've submitted a patch to remove the use of PATH_MAX
from gfortran. Apparently, there is at least one
target that does not define PATH_MAX. Please, don't
use PATH_MAX.
Here is the new patch, without PATH_MAX. OK to commit?
FX
2005-08-07 Francois-Xavier Coudert <coudert@clipper.ens.fr>
* acinclude.m4 (LIBGFOR_CHECK_UNLINK_OPEN_FILE): Add check to see
if target can unlink open files.
* configure.ac: Use this new test.
* config.h.in: Regenerate.
* configure: Regenerate.
* io/io.h: Add prototype for unpack_filename.
* io/close.c (st_close): Delete file after closing unit if
HAVE_UNLINK_OPEN_FILE is not defined.
* io/unix.c (unpack_filename): Unlink scratch file after opening
it only if HAVE_UNLINK_OPEN_FILE is defined.
Index: libgfortran/acinclude.m4
===================================================================
RCS file: /cvs/gcc/gcc/libgfortran/acinclude.m4,v
retrieving revision 1.5
diff -u -3 -p -r1.5 acinclude.m4
--- libgfortran/acinclude.m4 12 Dec 2004 08:59:01 -0000 1.5
+++ libgfortran/acinclude.m4 7 Aug 2005 17:58:03 -0000
@@ -148,3 +148,38 @@ extern void bar(void) __attribute__((ali
AC_DEFINE(HAVE_ATTRIBUTE_ALIAS, 1,
[Define to 1 if the target supports __attribute__((alias(...))).])
fi])
+
+dnl Check whether target can unlink a file still open.
+AC_DEFUN([LIBGFOR_CHECK_UNLINK_OPEN_FILE], [
+ AC_CACHE_CHECK([whether the target can unlink an open file],
+ have_unlink_open_file, [
+ AC_TRY_RUN([
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+int main ()
+{
+ int fd;
+
+ fd = open ("testfile", O_RDWR | O_CREAT, S_IWRITE | S_IREAD);
+ if (fd <= 0)
+ return 0;
+ if (unlink ("testfile") == -1)
+ return 1;
+ write (fd, "This is a test\n", 15);
+ close (fd);
+
+ if (open ("testfile", O_RDONLY, S_IWRITE | S_IREAD) == -1 && errno == ENOENT)
+ return 0;
+ else
+ return 1;
+}], have_unlink_open_file=yes, have_unlink_open_file=no, [
+case "${target}" in
+ *mingw*) have_unlink_open_file=no ;;
+ *) have_unlink_open_file=yes;;
+esac])])
+if test x"$have_unlink_open_file" = xyes; then
+ AC_DEFINE(HAVE_UNLINK_OPEN_FILE, 1, [Define if target can unlink open files.])
+fi])
Index: libgfortran/configure.ac
===================================================================
RCS file: /cvs/gcc/gcc/libgfortran/configure.ac,v
retrieving revision 1.30
diff -u -3 -p -r1.30 configure.ac
--- libgfortran/configure.ac 24 Jun 2005 23:07:13 -0000 1.30
+++ libgfortran/configure.ac 7 Aug 2005 17:58:03 -0000
@@ -258,6 +258,9 @@ LIBGFOR_CHECK_ATTRIBUTE_VISIBILITY
LIBGFOR_CHECK_ATTRIBUTE_DLLEXPORT
LIBGFOR_CHECK_ATTRIBUTE_ALIAS
+# Various other checks on target
+LIBGFOR_CHECK_UNLINK_OPEN_FILE
+
AC_CACHE_SAVE
if test ${multilib} = yes; then
Index: libgfortran/io/close.c
===================================================================
RCS file: /cvs/gcc/gcc/libgfortran/io/close.c,v
retrieving revision 1.6
diff -u -3 -p -r1.6 close.c
--- libgfortran/io/close.c 15 May 2005 12:44:41 -0000 1.6
+++ libgfortran/io/close.c 7 Aug 2005 17:58:03 -0000
@@ -30,6 +30,7 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "libgfortran.h"
#include "io.h"
+#include <limits.h>
typedef enum
{ CLOSE_DELETE, CLOSE_KEEP, CLOSE_UNSPECIFIED }
@@ -50,6 +51,9 @@ st_close (void)
{
close_status status;
gfc_unit *u;
+#if !HAVE_UNLINK_OPEN_FILE
+ char * path;
+#endif
library_start ();
@@ -68,14 +72,30 @@ st_close (void)
if (status == CLOSE_KEEP)
generate_error (ERROR_BAD_OPTION,
"Can't KEEP a scratch file on CLOSE");
+#if !HAVE_UNLINK_OPEN_FILE
+ path = (char *) alloca (u->file_len + 1);
+ unpack_filename (path, u->file, u->file_len);
+#endif
}
else
{
if (status == CLOSE_DELETE)
- delete_file (u);
+ {
+#if HAVE_UNLINK_OPEN_FILE
+ delete_file (u);
+#else
+ path = (char *) alloca (u->file_len + 1);
+ unpack_filename (path, u->file, u->file_len);
+#endif
+ }
}
close_unit (u);
+
+#if !HAVE_UNLINK_OPEN_FILE
+ if (u->flags.status == STATUS_SCRATCH || status == CLOSE_DELETE)
+ unlink (path);
+#endif
}
library_end ();
Index: libgfortran/io/io.h
===================================================================
RCS file: /cvs/gcc/gcc/libgfortran/io/io.h,v
retrieving revision 1.23
diff -u -3 -p -r1.23 io.h
--- libgfortran/io/io.h 6 Aug 2005 22:57:46 -0000 1.23
+++ libgfortran/io/io.h 7 Aug 2005 17:58:03 -0000
@@ -499,6 +499,9 @@ internal_proto(flush);
extern int unit_to_fd (int);
internal_proto(unit_to_fd);
+extern int unpack_filename (char *, const char *, int);
+internal_proto(unpack_filename);
+
/* unit.c */
extern void insert_unit (gfc_unit *);
Index: libgfortran/io/unix.c
===================================================================
RCS file: /cvs/gcc/gcc/libgfortran/io/unix.c,v
retrieving revision 1.32
diff -u -3 -p -r1.32 unix.c
--- libgfortran/io/unix.c 6 Aug 2005 22:57:46 -0000 1.32
+++ libgfortran/io/unix.c 7 Aug 2005 17:58:04 -0000
@@ -952,7 +952,7 @@ unit_to_fd(int unit)
* buffer that is PATH_MAX characters, convert the fortran string to a
* C string in the buffer. Returns nonzero if this is not possible. */
-static int
+int
unpack_filename (char *cstring, const char *fstring, int len)
{
len = fstrlen (fstring, len);
@@ -1136,8 +1136,11 @@ open_external (unit_flags *flags)
fd = tempfile ();
if (flags->action == ACTION_UNSPECIFIED)
flags->action = ACTION_READWRITE;
+
+#if HAVE_UNLINK_OPEN_FILE
/* We can unlink scratch files now and it will go away when closed. */
unlink (ioparm.file);
+#endif
}
else
{