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); |