summaryrefslogtreecommitdiff
path: root/libgfortran
diff options
context:
space:
mode:
authorjb <jb@138bc75d-0d04-0410-961f-82ee72b054a4>2014-09-16 21:40:28 +0000
committerjb <jb@138bc75d-0d04-0410-961f-82ee72b054a4>2014-09-16 21:40:28 +0000
commit8d832ee40150dc53add764cb067cbeb7afcf593e (patch)
tree34b3e91356fc23c2feb76d92e78fad28bd83a126 /libgfortran
parentad1321db5a15a7b784660be5f356c8c76cf19af9 (diff)
downloadgcc-8d832ee40150dc53add764cb067cbeb7afcf593e.tar.gz
PR libfortran/62768 Handle filenames with embedded null characters.
testsuite ChangeLog: 2014-09-17 Janne Blomqvist <jb@gcc.gnu.org> PR libfortran/62768 * gfortran.dg/filename_null.f90: New test. libgfortran ChangeLog: 2014-09-17 Janne Blomqvist <jb@gcc.gnu.org> PR libfortran/62768 * io/io.h (gfc_unit): Store C string for the filename. * io/close.c (st_close): Use gfc_unit.filename. * io/inquire.c (inquire_via_unit): Likewise. * io/open.c (new_unit): Likewise. (already_open): Likewise, unlink file before freeing filename. * io/unit.c (init_units): Likewise. (close_unit_1): Likewise. (filename_from_unit): Likewise. * io/unix.c (compare_file_filename): Likewise. (find_file0): Likewise. (delete_file): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@215307 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgfortran')
-rw-r--r--libgfortran/ChangeLog15
-rw-r--r--libgfortran/io/close.c4
-rw-r--r--libgfortran/io/inquire.c4
-rw-r--r--libgfortran/io/io.h5
-rw-r--r--libgfortran/io/open.c21
-rw-r--r--libgfortran/io/unit.c19
-rw-r--r--libgfortran/io/unix.c17
7 files changed, 39 insertions, 46 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 29c35fa6277..fde3965e5eb 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,18 @@
+2014-09-17 Janne Blomqvist <jb@gcc.gnu.org>
+
+ PR libfortran/62768
+ * io/io.h (gfc_unit): Store C string for the filename.
+ * io/close.c (st_close): Use gfc_unit.filename.
+ * io/inquire.c (inquire_via_unit): Likewise.
+ * io/open.c (new_unit): Likewise.
+ (already_open): Likewise, unlink file before freeing filename.
+ * io/unit.c (init_units): Likewise.
+ (close_unit_1): Likewise.
+ (filename_from_unit): Likewise.
+ * io/unix.c (compare_file_filename): Likewise.
+ (find_file0): Likewise.
+ (delete_file): Likewise.
+
2014-09-10 Janne Blomqvist <jb@gcc.gnu.org>
* io/transfer.c (read_block_form): Fix pad status check (found by
diff --git a/libgfortran/io/close.c b/libgfortran/io/close.c
index 55f49da831e..d0d49f697c4 100644
--- a/libgfortran/io/close.c
+++ b/libgfortran/io/close.c
@@ -72,7 +72,7 @@ st_close (st_parameter_close *clp)
generate_error (&clp->common, LIBERROR_BAD_OPTION,
"Can't KEEP a scratch file on CLOSE");
#if !HAVE_UNLINK_OPEN_FILE
- path = fc_strdup (u->file, u->file_len);
+ path = strdup (u->filename);
#endif
}
else
@@ -82,7 +82,7 @@ st_close (st_parameter_close *clp)
#if HAVE_UNLINK_OPEN_FILE
delete_file (u);
#else
- path = fc_strdup (u->file, u->file_len);
+ path = strdup (u->filename);
#endif
}
}
diff --git a/libgfortran/io/inquire.c b/libgfortran/io/inquire.c
index c41237c3ec7..4d03161cbf8 100644
--- a/libgfortran/io/inquire.c
+++ b/libgfortran/io/inquire.c
@@ -80,10 +80,10 @@ inquire_via_unit (st_parameter_inquire *iqp, gfc_unit * u)
memset (&iqp->name[tmplen], ' ', iqp->name_len - tmplen);
}
else /* If ttyname does not work, go with the default. */
- fstrcpy (iqp->name, iqp->name_len, u->file, u->file_len);
+ cf_strcpy (iqp->name, iqp->name_len, u->filename);
}
else
- fstrcpy (iqp->name, iqp->name_len, u->file, u->file_len);
+ cf_strcpy (iqp->name, iqp->name_len, u->filename);
#elif defined __MINGW32__
if (u->unit_number == options.stdin_unit)
fstrcpy (iqp->name, iqp->name_len, "CONIN$", sizeof("CONIN$"));
diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h
index 4e71d4953b1..1e0d092976d 100644
--- a/libgfortran/io/io.h
+++ b/libgfortran/io/io.h
@@ -567,8 +567,9 @@ typedef struct gfc_unit
array_loop_spec *ls;
int rank;
- int file_len;
- char *file;
+ /* Name of the file at the time OPEN was executed, as a
+ null-terminated C string. */
+ char *filename;
/* The format hash table. */
struct format_hash_entry format_hash_table[FORMAT_HASH_SIZE];
diff --git a/libgfortran/io/open.c b/libgfortran/io/open.c
index b803859ac3d..67fa9ac11aa 100644
--- a/libgfortran/io/open.c
+++ b/libgfortran/io/open.c
@@ -541,7 +541,6 @@ new_unit (st_parameter_open *opp, gfc_unit *u, unit_flags * flags)
/* Create the unit structure. */
- u->file = xmalloc (opp->file_len);
if (u->unit_number != opp->common.unit)
internal_error (&opp->common, "Unit number changed");
u->s = s;
@@ -618,8 +617,7 @@ new_unit (st_parameter_open *opp, gfc_unit *u, unit_flags * flags)
u->strm_pos = stell (u->s) + 1;
}
- memmove (u->file, opp->file, opp->file_len);
- u->file_len = opp->file_len;
+ u->filename = fc_strdup (opp->file, opp->file_len);
/* Curiously, the standard requires that the
position specifier be ignored for new files so a newly connected
@@ -685,20 +683,13 @@ already_open (st_parameter_open *opp, gfc_unit * u, unit_flags * flags)
}
u->s = NULL;
- free (u->file);
- u->file = NULL;
- u->file_len = 0;
-
+
#if !HAVE_UNLINK_OPEN_FILE
- char *path = NULL;
- if (u->file && u->flags.status == STATUS_SCRATCH)
- path = fc_strdup (u->file, u->file_len);
- if (path != NULL)
- {
- unlink (path);
- free (path);
- }
+ if (u->filename && u->flags.status == STATUS_SCRATCH)
+ unlink (u->filename);
#endif
+ free (u->filename);
+ u->filename = NULL;
u = new_unit (opp, u, flags);
if (u != NULL)
diff --git a/libgfortran/io/unit.c b/libgfortran/io/unit.c
index 22b315a4fd3..5cc51b56766 100644
--- a/libgfortran/io/unit.c
+++ b/libgfortran/io/unit.c
@@ -587,9 +587,7 @@ init_units (void)
u->recl = options.default_recl;
u->endfile = NO_ENDFILE;
- u->file_len = strlen (stdin_name);
- u->file = xmalloc (u->file_len);
- memmove (u->file, stdin_name, u->file_len);
+ u->filename = strdup (stdin_name);
fbuf_init (u, 0);
@@ -618,9 +616,7 @@ init_units (void)
u->recl = options.default_recl;
u->endfile = AT_ENDFILE;
- u->file_len = strlen (stdout_name);
- u->file = xmalloc (u->file_len);
- memmove (u->file, stdout_name, u->file_len);
+ u->filename = strdup (stdout_name);
fbuf_init (u, 0);
@@ -648,9 +644,7 @@ init_units (void)
u->recl = options.default_recl;
u->endfile = AT_ENDFILE;
- u->file_len = strlen (stderr_name);
- u->file = xmalloc (u->file_len);
- memmove (u->file, stderr_name, u->file_len);
+ u->filename = strdup (stderr_name);
fbuf_init (u, 256); /* 256 bytes should be enough, probably not doing
any kind of exotic formatting to stderr. */
@@ -689,9 +683,8 @@ close_unit_1 (gfc_unit *u, int locked)
delete_unit (u);
- free (u->file);
- u->file = NULL;
- u->file_len = 0;
+ free (u->filename);
+ u->filename = NULL;
free_format_hash_table (u);
fbuf_destroy (u);
@@ -804,7 +797,7 @@ filename_from_unit (int n)
/* Get the filename. */
if (u != NULL)
- return fc_strdup (u->file, u->file_len);
+ return strdup (u->filename);
else
return (char *) NULL;
}
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
index 9ad293b60a4..d30c6e5e33a 100644
--- a/libgfortran/io/unix.c
+++ b/libgfortran/io/unix.c
@@ -1525,11 +1525,7 @@ compare_file_filename (gfc_unit *u, const char *name, int len)
goto done;
}
# endif
-
- if (len != u->file_len)
- ret = 0;
- else
- ret = (memcmp(path, u->file, len) == 0);
+ ret = (strcmp(path, u->filename) == 0);
#endif
done:
free (path);
@@ -1541,8 +1537,8 @@ compare_file_filename (gfc_unit *u, const char *name, int len)
# define FIND_FILE0_DECL struct stat *st
# define FIND_FILE0_ARGS st
#else
-# define FIND_FILE0_DECL uint64_t id, const char *file, gfc_charlen_type file_len
-# define FIND_FILE0_ARGS id, file, file_len
+# define FIND_FILE0_DECL uint64_t id, const char *path
+# define FIND_FILE0_ARGS id, path
#endif
/* find_file0()-- Recursive work function for find_file() */
@@ -1574,7 +1570,7 @@ find_file0 (gfc_unit *u, FIND_FILE0_DECL)
}
else
# endif
- if (compare_string (u->file_len, u->file, file_len, file) == 0)
+ if (strcmp (u->filename, path) == 0)
return u;
#endif
@@ -1718,10 +1714,7 @@ flush_all_units (void)
int
delete_file (gfc_unit * u)
{
- char *path = fc_strdup (u->file, u->file_len);
- int err = unlink (path);
- free (path);
- return err;
+ return unlink (u->filename);
}