From 1e03060224b7b01b4da4aa423610e99abd1b2b17 Mon Sep 17 00:00:00 2001 From: Janne Blomqvist Date: Fri, 29 Apr 2011 19:09:45 +0300 Subject: [PATCH] Fix path handling From-SVN: r173172 --- libgfortran/ChangeLog | 15 +++++++++++++++ libgfortran/io/unix.c | 42 ++++++++++++++++++++++++++---------------- 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 89ae12565ed..79a1b7f99dc 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,18 @@ +2011-04-29 Janne Blomqvist + + * io/unix.c (min): New macro. + (unpack_filename): Return errno number for errors. + (regular_file): Use appropriately sized buffer for path. + (compare_file_filename): Likewise. + (find_file): Likewise. + (delete_file): Likewise. + (file_exists): Likewise. + (file_size): Likewise. + (inquire_sequential): Likewise. + (inquire_direct): Likewise. + (inquire_formatted): Likewise. + (inquire_access): Likewise. + 2011-04-29 Janne Blomqvist PR libfortran/48488 diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c index ee2fd172517..4e4bc3b1ee5 100644 --- a/libgfortran/io/unix.c +++ b/libgfortran/io/unix.c @@ -41,6 +41,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #include +/* min macro that evaluates its arguments only once. */ +#define min(a,b) \ + ({ typeof (a) _a = (a); \ + typeof (b) _b = (b); \ + _a < _b ? _a : _b; }) + + /* For mingw, we don't identify files by their inode number, but by a 64-bit identifier created from a BY_HANDLE_FILE_INFORMATION. */ #ifdef __MINGW32__ @@ -996,10 +1003,10 @@ int unpack_filename (char *cstring, const char *fstring, int len) { if (fstring == NULL) - return 1; + return EFAULT; len = fstrlen (fstring, len); if (len >= PATH_MAX) - return 1; + return ENAMETOOLONG; memmove (cstring, fstring, len); cstring[len] = '\0'; @@ -1124,15 +1131,17 @@ tempfile (st_parameter_open *opp) static int regular_file (st_parameter_open *opp, unit_flags *flags) { - char path[PATH_MAX + 1]; + char path[min(PATH_MAX, opp->file_len + 1)]; int mode; int rwflag; int crflag; int fd; + int err; - if (unpack_filename (path, opp->file, opp->file_len)) + err = unpack_filename (path, opp->file, opp->file_len); + if (err) { - errno = ENOENT; /* Fake an OS error */ + errno = err; /* Fake an OS error */ return -1; } @@ -1406,7 +1415,7 @@ st_printf (const char *format, ...) int compare_file_filename (gfc_unit *u, const char *name, int len) { - char path[PATH_MAX + 1]; + char path[min(PATH_MAX, len + 1)]; struct stat st; #ifdef HAVE_WORKING_STAT unix_stream *s; @@ -1506,7 +1515,7 @@ find_file0 (gfc_unit *u, FIND_FILE0_DECL) gfc_unit * find_file (const char *file, gfc_charlen_type file_len) { - char path[PATH_MAX + 1]; + char path[min(PATH_MAX, file_len + 1)]; struct stat st[1]; gfc_unit *u; #if defined(__MINGW32__) && !HAVE_WORKING_STAT @@ -1625,11 +1634,12 @@ flush_all_units (void) int delete_file (gfc_unit * u) { - char path[PATH_MAX + 1]; + char path[min(PATH_MAX, u->file_len + 1)]; + int err = unpack_filename (path, u->file, u->file_len); - if (unpack_filename (path, u->file, u->file_len)) + if (err) { /* Shouldn't be possible */ - errno = ENOENT; + errno = err; return 1; } @@ -1643,7 +1653,7 @@ delete_file (gfc_unit * u) int file_exists (const char *file, gfc_charlen_type file_len) { - char path[PATH_MAX + 1]; + char path[min(PATH_MAX, file_len + 1)]; if (unpack_filename (path, file, file_len)) return 0; @@ -1657,7 +1667,7 @@ file_exists (const char *file, gfc_charlen_type file_len) GFC_IO_INT file_size (const char *file, gfc_charlen_type file_len) { - char path[PATH_MAX + 1]; + char path[min(PATH_MAX, file_len + 1)]; struct stat statbuf; if (unpack_filename (path, file, file_len)) @@ -1678,7 +1688,7 @@ static const char yes[] = "YES", no[] = "NO", unknown[] = "UNKNOWN"; const char * inquire_sequential (const char *string, int len) { - char path[PATH_MAX + 1]; + char path[min(PATH_MAX, len + 1)]; struct stat statbuf; if (string == NULL || @@ -1702,7 +1712,7 @@ inquire_sequential (const char *string, int len) const char * inquire_direct (const char *string, int len) { - char path[PATH_MAX + 1]; + char path[min(PATH_MAX, len + 1)]; struct stat statbuf; if (string == NULL || @@ -1726,7 +1736,7 @@ inquire_direct (const char *string, int len) const char * inquire_formatted (const char *string, int len) { - char path[PATH_MAX + 1]; + char path[min(PATH_MAX, len + 1)]; struct stat statbuf; if (string == NULL || @@ -1761,7 +1771,7 @@ inquire_unformatted (const char *string, int len) static const char * inquire_access (const char *string, int len, int mode) { - char path[PATH_MAX + 1]; + char path[min(PATH_MAX, len + 1)]; if (string == NULL || unpack_filename (path, string, len) || access (path, mode) < 0)