From: Simon Marlow Date: Wed, 23 Jan 2008 10:29:04 +0000 (+0000) Subject: Windows: large file support for hFileSize and hSeek (#1771) X-Git-Tag: 2008-05-28~83 X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=260c3a0aa9dc8e90c24cba659d709803d0804961;p=ghc-base.git Windows: large file support for hFileSize and hSeek (#1771) --- diff --git a/System/Posix/Internals.hs b/System/Posix/Internals.hs index 251a22d..3039ea5 100644 --- a/System/Posix/Internals.hs +++ b/System/Posix/Internals.hs @@ -83,7 +83,7 @@ fdFileSize fd = if not (s_isreg c_mode) then return (-1) else do - c_size <- st_size p_stat :: IO COff + c_size <- st_size p_stat return (fromIntegral c_size) data FDType = Directory | Stream | RegularFile | RawDevice @@ -346,8 +346,13 @@ foreign import ccall unsafe "HsBase.h getcwd" foreign import ccall unsafe "HsBase.h isatty" c_isatty :: CInt -> IO CInt +#if defined(mingw32_HOST_OS) || defined(__MINGW32__) +foreign import ccall unsafe "HsBase.h __hscore_lseek" + c_lseek :: CInt -> Int64 -> CInt -> IO Int64 +#else foreign import ccall unsafe "HsBase.h __hscore_lseek" c_lseek :: CInt -> COff -> CInt -> IO COff +#endif foreign import ccall unsafe "HsBase.h __hscore_lstat" lstat :: CString -> Ptr CStat -> IO CInt @@ -481,7 +486,11 @@ s_isfifo cm = c_s_isfifo cm /= 0 foreign import ccall unsafe "HsBase.h __hscore_sizeof_stat" sizeof_stat :: Int foreign import ccall unsafe "HsBase.h __hscore_st_mtime" st_mtime :: Ptr CStat -> IO CTime +#ifdef mingw32_HOST_OS +foreign import ccall unsafe "HsBase.h __hscore_st_size" st_size :: Ptr CStat -> IO Int64 +#else foreign import ccall unsafe "HsBase.h __hscore_st_size" st_size :: Ptr CStat -> IO COff +#endif foreign import ccall unsafe "HsBase.h __hscore_st_mode" st_mode :: Ptr CStat -> IO CMode foreign import ccall unsafe "HsBase.h __hscore_st_dev" st_dev :: Ptr CStat -> IO CDev foreign import ccall unsafe "HsBase.h __hscore_st_ino" st_ino :: Ptr CStat -> IO CIno diff --git a/include/HsBase.h b/include/HsBase.h index e067c25..7fae68a 100644 --- a/include/HsBase.h +++ b/include/HsBase.h @@ -491,18 +491,32 @@ __hscore_free_dirent(struct dirent *dEnt) #endif } +#if defined(__MINGW32__) +// We want the versions of stat/fstat/lseek that use 64-bit offsets, +// and you have to ask for those explicitly. Unfortunately there +// doesn't seem to be a 64-bit version of truncate/ftruncate, so while +// hFileSize and hSeek will work with large files, hSetFileSize will not. +#define stat(file,buf) _stati64(file,buf) +#define fstat(fd,buf) _fstati64(fd,buf) +typedef struct _stati64 struct_stat; +typedef off64_t stsize_t; +#else +typedef struct stat struct_stat; +typedef off_t stsize_t; +#endif + INLINE HsInt __hscore_sizeof_stat( void ) { - return sizeof(struct stat); + return sizeof(struct_stat); } -INLINE time_t __hscore_st_mtime ( struct stat* st ) { return st->st_mtime; } -INLINE off_t __hscore_st_size ( struct stat* st ) { return st->st_size; } +INLINE time_t __hscore_st_mtime ( struct_stat* st ) { return st->st_mtime; } +INLINE stsize_t __hscore_st_size ( struct_stat* st ) { return st->st_size; } #if !defined(_MSC_VER) -INLINE mode_t __hscore_st_mode ( struct stat* st ) { return st->st_mode; } -INLINE mode_t __hscore_st_dev ( struct stat* st ) { return st->st_dev; } -INLINE mode_t __hscore_st_ino ( struct stat* st ) { return st->st_ino; } +INLINE mode_t __hscore_st_mode ( struct_stat* st ) { return st->st_mode; } +INLINE mode_t __hscore_st_dev ( struct_stat* st ) { return st->st_dev; } +INLINE mode_t __hscore_st_ino ( struct_stat* st ) { return st->st_ino; } #endif #if HAVE_TERMIOS_H @@ -652,15 +666,21 @@ INLINE int __hscore_open(char *file, int how, mode_t mode) { // macros which redirect to the 64-bit-off_t versions when large file // support is enabled. // +#if defined(__MINGW32__) +INLINE off64_t __hscore_lseek(int fd, off64_t off, int whence) { + return (_lseeki64(fd,off,whence)); +} +#else INLINE off_t __hscore_lseek(int fd, off_t off, int whence) { return (lseek(fd,off,whence)); } +#endif -INLINE int __hscore_stat(char *file, struct stat *buf) { +INLINE int __hscore_stat(char *file, struct_stat *buf) { return (stat(file,buf)); } -INLINE int __hscore_fstat(int fd, struct stat *buf) { +INLINE int __hscore_fstat(int fd, struct_stat *buf) { return (fstat(fd,buf)); }