diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 68bf89705d6e..280ac230a7dd 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,26 @@ +2009-12-04 Janne Blomqvist + + 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 * gfortran.map: Add _gfortran_is_extension_of. diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c index 8b324759a733..07aa4d95972a 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 +#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 f0f0712457a4..e691982e505d 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 bba95f7c7813..dd63fa4e6169 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 #endif + +#ifdef __MINGW32__ +typedef off64_t gfc_offset; +#else typedef off_t gfc_offset; +#endif #ifndef NULL #define NULL (void *) 0