summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjb <jb@138bc75d-0d04-0410-961f-82ee72b054a4>2009-12-04 16:28:44 +0000
committerjb <jb@138bc75d-0d04-0410-961f-82ee72b054a4>2009-12-04 16:28:44 +0000
commit4dbc065859bd48a6c865105eef41fa00606ad173 (patch)
treea435ab3b0975b61493223bb3a25af26b5f2a3e5b
parentd66a47eece163b82733144c7c26e8d10f060d5e5 (diff)
downloadgcc-4dbc065859bd48a6c865105eef41fa00606ad173.tar.gz
PR libfortran/40812 Large file support for MinGW
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154984 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libgfortran/ChangeLog23
-rw-r--r--libgfortran/io/unix.c63
-rw-r--r--libgfortran/io/unix.h14
-rw-r--r--libgfortran/libgfortran.h5
4 files changed, 83 insertions, 22 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 68bf89705d6..280ac230a7d 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,26 @@
+2009-12-04 Janne Blomqvist <jb@gcc.gnu.org>
+
+ PR libfortran/40812
+ * libgfortran.h: typedef gfc_offset differently for MinGW.
+ * io/unix.h (struct stream): Change function pointers to use
+ gfc_offset instead of off_t.
+ (sseek): Change prototype to use gfc_offset instead of off_t.
+ (stell): Likewise.
+ (struncate): Likewise.
+ * io/unix.c: Redefine lseek() for mingw.
+ (raw_seek): Use gfc_offset instead of off_t.
+ (raw_tell): Likewise.
+ (buf_seek): Likewise.
+ (buf_tell): Likewise.
+ (buf_truncate): Likewise.
+ (mem_seek): Likewise.
+ (mem_tell): Likewise.
+ (mem_truncate): Likewise.
+ (fd_to_stream): Likewise.
+ (file_length): Likewise.
+ (raw_truncate): Use gfc_offset instead of off_t, add large file
+ capable implementation for MinGW.
+
2009-11-30 Janus Weil <janus@gcc.gnu.org>
* gfortran.map: Add _gfortran_is_extension_of.
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
index 8b324759a73..07aa4d95972 100644
--- a/libgfortran/io/unix.c
+++ b/libgfortran/io/unix.c
@@ -47,6 +47,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+#define lseek _lseeki64
+
static uint64_t
id_from_handle (HANDLE hFile)
{
@@ -274,22 +276,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);
@@ -470,8 +503,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)
{
@@ -495,14 +528,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;
@@ -631,8 +664,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)
@@ -668,7 +701,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;
@@ -677,7 +710,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;
}
@@ -764,7 +797,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;
@@ -1602,7 +1635,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);
diff --git a/libgfortran/io/unix.h b/libgfortran/io/unix.h
index f0f0712457a..e691982e505 100644
--- a/libgfortran/io/unix.h
+++ b/libgfortran/io/unix.h
@@ -33,10 +33,10 @@ struct stream
{
ssize_t (*read) (struct stream *, void *, ssize_t);
ssize_t (*write) (struct stream *, const void *, ssize_t);
- off_t (*seek) (struct stream *, off_t, int);
- off_t (*tell) (struct stream *);
+ gfc_offset (*seek) (struct stream *, gfc_offset, int);
+ gfc_offset (*tell) (struct stream *);
/* Avoid keyword truncate due to AIX namespace collision. */
- int (*trunc) (struct stream *, off_t);
+ int (*trunc) (struct stream *, gfc_offset);
int (*flush) (struct stream *);
int (*close) (struct stream *);
};
@@ -54,20 +54,20 @@ swrite (stream * s, const void * buf, ssize_t nbyte)
return s->write (s, buf, nbyte);
}
-static inline off_t
-sseek (stream * s, off_t offset, int whence)
+static inline gfc_offset
+sseek (stream * s, gfc_offset offset, int whence)
{
return s->seek (s, offset, whence);
}
-static inline off_t
+static inline gfc_offset
stell (stream * s)
{
return s->tell (s);
}
static inline int
-struncate (stream * s, off_t length)
+struncate (stream * s, gfc_offset length)
{
return s->trunc (s, length);
}
diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h
index bba95f7c781..dd63fa4e616 100644
--- a/libgfortran/libgfortran.h
+++ b/libgfortran/libgfortran.h
@@ -56,7 +56,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
+
+#ifdef __MINGW32__
+typedef off64_t gfc_offset;
+#else
typedef off_t gfc_offset;
+#endif
#ifndef NULL
#define NULL (void *) 0