#include <errno.h>
+/* 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__
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';
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;
}
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;
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
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;
}
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;
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))
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 ||
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 ||
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 ||
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)