Windows: Unicode openFile and stat functions
authorSimon Marlow <marlowsd@gmail.com>
Thu, 18 Jun 2009 13:54:58 +0000 (13:54 +0000)
committerSimon Marlow <marlowsd@gmail.com>
Thu, 18 Jun 2009 13:54:58 +0000 (13:54 +0000)
GHC/IO/FD.hs
System/IO.hs
System/Posix/Internals.hs
include/HsBase.h

index 7ceffc3..a54dd52 100644 (file)
@@ -130,7 +130,7 @@ writeBuf' fd buf = do
 -- into non-blocking mode on Unix systems.
 openFile :: FilePath -> IOMode -> IO (FD,IODeviceType)
 openFile filepath iomode =
-  withCString filepath $ \ f ->
+  withFilePath filepath $ \ f ->
 
     let 
       oflags1 = case iomode of
index f6d1b75..87025c3 100644 (file)
@@ -168,7 +168,6 @@ import Data.Bits
 import Data.List
 import Data.Maybe
 import Foreign.C.Error
-import Foreign.C.String
 import Foreign.C.Types
 import System.Posix.Internals
 #endif
@@ -474,7 +473,7 @@ openTempFile' loc tmp_dir template binary = do
                         return (filepath, h)
 #else
     findTempName x = do
-      fd <- withCString filepath $ \ f ->
+      fd <- withFilePath filepath $ \ f ->
               c_open f oflags 0o600
       if fd < 0
        then do
index 26a8a5b..ac80574 100644 (file)
@@ -104,7 +104,7 @@ fdFileSize fd =
 fileType :: FilePath -> IO IODeviceType
 fileType file =
   allocaBytes sizeof_stat $ \ p_stat -> do
-  withCString file $ \p_file -> do
+  withFilePath file $ \p_file -> do
     throwErrnoIfMinus1Retry "fileType" $
       c_stat p_file p_stat
     statGetType p_stat
@@ -172,6 +172,14 @@ fdGetMode fd = do
           
     return mode
 
+#ifdef mingw32_HOST_OS
+withFilePath :: FilePath -> (CWString -> IO a) -> IO a
+withFilePath = withCWString 
+#else
+withFilePath :: FilePath -> (CString -> IO a) -> IO a
+withFilePath = withCString
+#endif
+
 -- ---------------------------------------------------------------------------
 -- Terminal-related stuff
 
@@ -338,6 +346,12 @@ setCloseOnExec fd = do
 -- -----------------------------------------------------------------------------
 -- foreign imports
 
+#if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
+type CFilePath = CString
+#else
+type CFilePath = CWString
+#endif
+
 foreign import ccall unsafe "HsBase.h access"
    c_access :: CString -> CInt -> IO CInt
 
@@ -374,10 +388,10 @@ foreign import ccall unsafe "HsBase.h __hscore_lseek"
 #endif
 
 foreign import ccall unsafe "HsBase.h __hscore_lstat"
-   lstat :: CString -> Ptr CStat -> IO CInt
+   lstat :: CFilePath -> Ptr CStat -> IO CInt
 
-foreign import ccall unsafe "HsBase.h __hscore_open"
-   c_open :: CString -> CInt -> CMode -> IO CInt
+foreign import ccall unsafe "__hscore_open"
+   c_open :: CFilePath -> CInt -> CMode -> IO CInt
 
 foreign import ccall unsafe "HsBase.h opendir" 
    c_opendir :: CString  -> IO (Ptr CDir)
@@ -391,8 +405,8 @@ foreign import ccall unsafe "HsBase.h read"
 foreign import ccall unsafe "HsBase.h rewinddir"
    c_rewinddir :: Ptr CDir -> IO ()
 
-foreign import ccall unsafe "HsBase.h __hscore_stat"
-   c_stat :: CString -> Ptr CStat -> IO CInt
+foreign import ccall unsafe "__hscore_stat"
+   c_stat :: CFilePath -> Ptr CStat -> IO CInt
 
 foreign import ccall unsafe "HsBase.h umask"
    c_umask :: CMode -> IO CMode
index 6ed0faa..ccabc1e 100644 (file)
@@ -456,16 +456,6 @@ __hscore_mkdir( char *pathName, int mode )
 #endif
 }
 
-INLINE int
-__hscore_lstat( const char *fname, struct stat *st )
-{
-#if HAVE_LSTAT
-  return lstat(fname, st);
-#else
-  return stat(fname, st);
-#endif
-}
-
 INLINE char *
 __hscore_d_name( struct dirent* d )
 {
@@ -491,8 +481,6 @@ __hscore_free_dirent(struct dirent *dEnt)
 // 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
@@ -514,6 +502,37 @@ INLINE dev_t  __hscore_st_dev  ( struct_stat* st ) { return st->st_dev; }
 INLINE ino_t  __hscore_st_ino  ( struct_stat* st ) { return st->st_ino; }
 #endif
 
+#if defined(__MINGW32__)
+INLINE int __hscore_stat(wchar_t *file, struct_stat *buf) {
+       return _wstati64(file,buf);
+}
+
+INLINE int __hscore_fstat(int fd, struct_stat *buf) {
+       return _fstati64(fd,buf);
+}
+INLINE int __hscore_lstat(wchar_t *fname, struct_stat *buf )
+{
+       return _wstati64(fname,buf);
+}
+#else
+INLINE int __hscore_stat(char *file, struct_stat *buf) {
+       return stat(file,buf);
+}
+
+INLINE int __hscore_fstat(int fd, struct_stat *buf) {
+       return fstat(fd,buf);
+}
+
+INLINE int __hscore_lstat( const char *fname, struct stat *buf )
+{
+#if HAVE_LSTAT
+  return lstat(fname, buf);
+#else
+  return stat(fname, buf);
+#endif
+}
+#endif
+
 #if HAVE_TERMIOS_H
 INLINE tcflag_t __hscore_lflag( struct termios* ts ) { return ts->c_lflag; }
 
@@ -673,18 +692,20 @@ extern void __hscore_set_saved_termios(int fd, void* ts);
 
 INLINE int __hscore_hs_fileno (FILE *f) { return fileno (f); }
 
-INLINE int __hscore_open(char *file, int how, mode_t mode) {
 #ifdef __MINGW32__
+INLINE int __hscore_open(wchar_t *file, int how, mode_t mode) {
        if ((how & O_WRONLY) || (how & O_RDWR) || (how & O_APPEND))
-         return _sopen(file,how | _O_NOINHERIT,_SH_DENYRW,mode);
+         return _wsopen(file,how | _O_NOINHERIT,_SH_DENYRW,mode);
           // _O_NOINHERIT: see #2650
        else
-         return _sopen(file,how | _O_NOINHERIT,_SH_DENYWR,mode);
+         return _wsopen(file,how | _O_NOINHERIT,_SH_DENYWR,mode);
           // _O_NOINHERIT: see #2650
+}
 #else
+INLINE int __hscore_open(char *file, int how, mode_t mode) {
        return open(file,how,mode);
-#endif
 }
+#endif
 
 // These are wrapped because on some OSs (eg. Linux) they are
 // macros which redirect to the 64-bit-off_t versions when large file
@@ -700,14 +721,6 @@ INLINE off_t __hscore_lseek(int fd, off_t off, int whence) {
 }
 #endif
 
-INLINE int __hscore_stat(char *file, struct_stat *buf) {
-       return (stat(file,buf));
-}
-
-INLINE int __hscore_fstat(int fd, struct_stat *buf) {
-       return (fstat(fd,buf));
-}
-
 // select-related stuff
 
 #if !defined(__MINGW32__)