| Index: gcc/libgfortran/io/unix.c
|
| diff --git a/gcc/libgfortran/io/unix.c b/gcc/libgfortran/io/unix.c
|
| index a7eb4e36ae5096a7f885df3d32bf4ed18193435b..32f38904f341bd6dc8887e8212f1749abf8a7285 100644
|
| --- a/gcc/libgfortran/io/unix.c
|
| +++ b/gcc/libgfortran/io/unix.c
|
| @@ -1,4 +1,4 @@
|
| -/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
| +/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
| Free Software Foundation, Inc.
|
| Contributed by Andy Vaught
|
| F2003 I/O support contributed by Jerry DeLisle
|
| @@ -27,6 +27,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
| /* Unix stream I/O module */
|
|
|
| #include "io.h"
|
| +#include "unix.h"
|
| #include <stdlib.h>
|
| #include <limits.h>
|
|
|
| @@ -41,11 +42,17 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
|
| /* For mingw, we don't identify files by their inode number, but by a
|
| 64-bit identifier created from a BY_HANDLE_FILE_INFORMATION. */
|
| -#if defined(__MINGW32__) && !HAVE_WORKING_STAT
|
| +#ifdef __MINGW32__
|
|
|
| #define WIN32_LEAN_AND_MEAN
|
| #include <windows.h>
|
|
|
| +#define lseek _lseeki64
|
| +#define fstat _fstati64
|
| +#define stat _stati64
|
| +typedef struct _stati64 gfstat_t;
|
| +
|
| +#ifndef HAVE_WORKING_STAT
|
| static uint64_t
|
| id_from_handle (HANDLE hFile)
|
| {
|
| @@ -89,6 +96,10 @@ id_from_fd (const int fd)
|
|
|
| #endif
|
|
|
| +#else
|
| +typedef struct stat gfstat_t;
|
| +#endif
|
| +
|
| #ifndef PATH_MAX
|
| #define PATH_MAX 1024
|
| #endif
|
| @@ -273,22 +284,53 @@ raw_write (unix_stream * s, const void * buf, ssize_t nbyte)
|
| return nbyte - bytes_left;
|
| }
|
|
|
| -static off_t
|
| -raw_seek (unix_stream * s, off_t offset, int whence)
|
| +static gfc_offset
|
| +raw_seek (unix_stream * s, gfc_offset offset, int whence)
|
| {
|
| return lseek (s->fd, offset, whence);
|
| }
|
|
|
| -static off_t
|
| +static gfc_offset
|
| raw_tell (unix_stream * s)
|
| {
|
| return lseek (s->fd, 0, SEEK_CUR);
|
| }
|
|
|
| static int
|
| -raw_truncate (unix_stream * s, off_t length)
|
| +raw_truncate (unix_stream * s, gfc_offset length)
|
| {
|
| -#ifdef HAVE_FTRUNCATE
|
| +#ifdef __MINGW32__
|
| + HANDLE h;
|
| + gfc_offset cur;
|
| +
|
| + if (isatty (s->fd))
|
| + {
|
| + errno = EBADF;
|
| + return -1;
|
| + }
|
| + h = _get_osfhandle (s->fd);
|
| + if (h == INVALID_HANDLE_VALUE)
|
| + {
|
| + errno = EBADF;
|
| + return -1;
|
| + }
|
| + cur = lseek (s->fd, 0, SEEK_CUR);
|
| + if (cur == -1)
|
| + return -1;
|
| + if (lseek (s->fd, length, SEEK_SET) == -1)
|
| + goto error;
|
| + if (!SetEndOfFile (h))
|
| + {
|
| + errno = EBADF;
|
| + goto error;
|
| + }
|
| + if (lseek (s->fd, cur, SEEK_SET) == -1)
|
| + return -1;
|
| + return 0;
|
| + error:
|
| + lseek (s->fd, cur, SEEK_SET);
|
| + return -1;
|
| +#elif defined HAVE_FTRUNCATE
|
| return ftruncate (s->fd, length);
|
| #elif defined HAVE_CHSIZE
|
| return chsize (s->fd, length);
|
| @@ -454,13 +496,17 @@ buf_write (unix_stream * s, const void * buf, ssize_t nbyte)
|
| s->ndirty += nbyte;
|
| }
|
| else
|
| - {
|
| - if (s->file_length != -1 && s->physical_offset != s->logical_offset
|
| - && lseek (s->fd, s->logical_offset, SEEK_SET) < 0)
|
| - return -1;
|
| - nbyte = raw_write (s, buf, nbyte);
|
| - s->physical_offset += nbyte;
|
| - }
|
| + {
|
| + if (s->file_length != -1 && s->physical_offset != s->logical_offset)
|
| + {
|
| + if (lseek (s->fd, s->logical_offset, SEEK_SET) < 0)
|
| + return -1;
|
| + s->physical_offset = s->logical_offset;
|
| + }
|
| +
|
| + nbyte = raw_write (s, buf, nbyte);
|
| + s->physical_offset += nbyte;
|
| + }
|
| }
|
| s->logical_offset += nbyte;
|
| /* Don't increment file_length if the file is non-seekable. */
|
| @@ -469,8 +515,8 @@ buf_write (unix_stream * s, const void * buf, ssize_t nbyte)
|
| return nbyte;
|
| }
|
|
|
| -static off_t
|
| -buf_seek (unix_stream * s, off_t offset, int whence)
|
| +static gfc_offset
|
| +buf_seek (unix_stream * s, gfc_offset offset, int whence)
|
| {
|
| switch (whence)
|
| {
|
| @@ -494,14 +540,14 @@ buf_seek (unix_stream * s, off_t offset, int whence)
|
| return offset;
|
| }
|
|
|
| -static off_t
|
| +static gfc_offset
|
| buf_tell (unix_stream * s)
|
| {
|
| return s->logical_offset;
|
| }
|
|
|
| static int
|
| -buf_truncate (unix_stream * s, off_t length)
|
| +buf_truncate (unix_stream * s, gfc_offset length)
|
| {
|
| int r;
|
|
|
| @@ -630,8 +676,8 @@ mem_write (stream * s, const void * buf, ssize_t nbytes)
|
| }
|
|
|
|
|
| -static off_t
|
| -mem_seek (stream * strm, off_t offset, int whence)
|
| +static gfc_offset
|
| +mem_seek (stream * strm, gfc_offset offset, int whence)
|
| {
|
| unix_stream * s = (unix_stream *) strm;
|
| switch (whence)
|
| @@ -667,7 +713,7 @@ mem_seek (stream * strm, off_t offset, int whence)
|
| }
|
|
|
|
|
| -static off_t
|
| +static gfc_offset
|
| mem_tell (stream * s)
|
| {
|
| return ((unix_stream *)s)->logical_offset;
|
| @@ -676,7 +722,7 @@ mem_tell (stream * s)
|
|
|
| static int
|
| mem_truncate (unix_stream * s __attribute__ ((unused)),
|
| - off_t length __attribute__ ((unused)))
|
| + gfc_offset length __attribute__ ((unused)))
|
| {
|
| return 0;
|
| }
|
| @@ -747,7 +793,7 @@ open_internal (char *base, int length, gfc_offset offset)
|
| static stream *
|
| fd_to_stream (int fd, int prot)
|
| {
|
| - struct stat statbuf;
|
| + gfstat_t statbuf;
|
| unix_stream *s;
|
|
|
| s = get_mem (sizeof (unix_stream));
|
| @@ -763,7 +809,7 @@ fd_to_stream (int fd, int prot)
|
|
|
| fstat (fd, &statbuf);
|
|
|
| - if (lseek (fd, 0, SEEK_CUR) == (off_t) -1)
|
| + if (lseek (fd, 0, SEEK_CUR) == (gfc_offset) -1)
|
| s->file_length = -1;
|
| else
|
| s->file_length = S_ISREG (statbuf.st_mode) ? statbuf.st_size : -1;
|
| @@ -897,6 +943,47 @@ regular_file (st_parameter_open *opp, unit_flags *flags)
|
| return -1;
|
| }
|
|
|
| +#ifdef __CYGWIN__
|
| + if (opp->file_len == 7)
|
| + {
|
| + if (strncmp (path, "CONOUT$", 7) == 0
|
| + || strncmp (path, "CONERR$", 7) == 0)
|
| + {
|
| + fd = open ("/dev/conout", O_WRONLY);
|
| + flags->action = ACTION_WRITE;
|
| + return fd;
|
| + }
|
| + }
|
| +
|
| + if (opp->file_len == 6 && strncmp (path, "CONIN$", 6) == 0)
|
| + {
|
| + fd = open ("/dev/conin", O_RDONLY);
|
| + flags->action = ACTION_READ;
|
| + return fd;
|
| + }
|
| +#endif
|
| +
|
| +
|
| +#ifdef __MINGW32__
|
| + if (opp->file_len == 7)
|
| + {
|
| + if (strncmp (path, "CONOUT$", 7) == 0
|
| + || strncmp (path, "CONERR$", 7) == 0)
|
| + {
|
| + fd = open ("CONOUT$", O_WRONLY);
|
| + flags->action = ACTION_WRITE;
|
| + return fd;
|
| + }
|
| + }
|
| +
|
| + if (opp->file_len == 6 && strncmp (path, "CONIN$", 6) == 0)
|
| + {
|
| + fd = open ("CONIN$", O_RDONLY);
|
| + flags->action = ACTION_READ;
|
| + return fd;
|
| + }
|
| +#endif
|
| +
|
| rwflag = 0;
|
|
|
| switch (flags->action)
|
| @@ -1145,9 +1232,9 @@ int
|
| compare_file_filename (gfc_unit *u, const char *name, int len)
|
| {
|
| char path[PATH_MAX + 1];
|
| - struct stat st1;
|
| + gfstat_t st1;
|
| #ifdef HAVE_WORKING_STAT
|
| - struct stat st2;
|
| + gfstat_t st2;
|
| #else
|
| # ifdef __MINGW32__
|
| uint64_t id1, id2;
|
| @@ -1186,7 +1273,7 @@ compare_file_filename (gfc_unit *u, const char *name, int len)
|
|
|
|
|
| #ifdef HAVE_WORKING_STAT
|
| -# define FIND_FILE0_DECL struct stat *st
|
| +# define FIND_FILE0_DECL gfstat_t *st
|
| # define FIND_FILE0_ARGS st
|
| #else
|
| # define FIND_FILE0_DECL uint64_t id, const char *file, gfc_charlen_type file_len
|
| @@ -1243,9 +1330,11 @@ gfc_unit *
|
| find_file (const char *file, gfc_charlen_type file_len)
|
| {
|
| char path[PATH_MAX + 1];
|
| - struct stat st[2];
|
| + gfstat_t st[2];
|
| gfc_unit *u;
|
| - uint64_t id;
|
| +#if defined(__MINGW32__) && !HAVE_WORKING_STAT
|
| + uint64_t id = 0ULL;
|
| +#endif
|
|
|
| if (unpack_filename (path, file, file_len))
|
| return NULL;
|
| @@ -1255,8 +1344,6 @@ find_file (const char *file, gfc_charlen_type file_len)
|
|
|
| #if defined(__MINGW32__) && !HAVE_WORKING_STAT
|
| id = id_from_path (path);
|
| -#else
|
| - id = 0;
|
| #endif
|
|
|
| __gthread_mutex_lock (&unit_lock);
|
| @@ -1380,7 +1467,7 @@ int
|
| file_exists (const char *file, gfc_charlen_type file_len)
|
| {
|
| char path[PATH_MAX + 1];
|
| - struct stat statbuf;
|
| + gfstat_t statbuf;
|
|
|
| if (unpack_filename (path, file, file_len))
|
| return 0;
|
| @@ -1392,6 +1479,22 @@ file_exists (const char *file, gfc_charlen_type file_len)
|
| }
|
|
|
|
|
| +/* file_size()-- Returns the size of the file. */
|
| +
|
| +GFC_IO_INT
|
| +file_size (const char *file, gfc_charlen_type file_len)
|
| +{
|
| + char path[PATH_MAX + 1];
|
| + gfstat_t statbuf;
|
| +
|
| + if (unpack_filename (path, file, file_len))
|
| + return -1;
|
| +
|
| + if (stat (path, &statbuf) < 0)
|
| + return -1;
|
| +
|
| + return (GFC_IO_INT) statbuf.st_size;
|
| +}
|
|
|
| static const char yes[] = "YES", no[] = "NO", unknown[] = "UNKNOWN";
|
|
|
| @@ -1403,7 +1506,7 @@ const char *
|
| inquire_sequential (const char *string, int len)
|
| {
|
| char path[PATH_MAX + 1];
|
| - struct stat statbuf;
|
| + gfstat_t statbuf;
|
|
|
| if (string == NULL ||
|
| unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
|
| @@ -1427,7 +1530,7 @@ const char *
|
| inquire_direct (const char *string, int len)
|
| {
|
| char path[PATH_MAX + 1];
|
| - struct stat statbuf;
|
| + gfstat_t statbuf;
|
|
|
| if (string == NULL ||
|
| unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
|
| @@ -1451,7 +1554,7 @@ const char *
|
| inquire_formatted (const char *string, int len)
|
| {
|
| char path[PATH_MAX + 1];
|
| - struct stat statbuf;
|
| + gfstat_t statbuf;
|
|
|
| if (string == NULL ||
|
| unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
|
| @@ -1560,7 +1663,7 @@ inquire_readwrite (const char *string, int len)
|
| gfc_offset
|
| file_length (stream * s)
|
| {
|
| - off_t curr, end;
|
| + gfc_offset curr, end;
|
| if (!is_seekable (s))
|
| return -1;
|
| curr = stell (s);
|
|
|