diff options
author | simonmar <unknown> | 2002-09-06 14:34:15 +0000 |
---|---|---|
committer | simonmar <unknown> | 2002-09-06 14:34:15 +0000 |
commit | ad174ba59098b984b69073a721c1976579270fee (patch) | |
tree | 1c224369761abc3c0e74b07fd9097077f85ed642 /System/Posix/Directory.hsc |
[project @ 2002-09-06 14:34:15 by simonmar]
Partial rewrite of the POSIX library.
The main purpose of this sweep is to remove the last dependencies of
the compiler on hslibs. When I've committed the associated compiler
changes, only the 'base' package will be required to bootstrap the
compiler. Additionally to build GHCi, the 'readline' and 'unix'
packages will be required.
The new POSIX library lives mostly in libraries/unix, with a few bits
required for compiler bootstrapping in libraries/base. The 'base'
package is mostly free of hsc2hs code to make bootstrapping from HC
files easier, but the 'unix' package will use hsc2hs liberally.
The old POSIX library continues to provide more-or-less the same
interface as before, although some of the types are more correct now
(previously lots of POSIX types were just mapped to Int). The new
interface is largely the same as the old, except that some new
functionality from the latest POSIX spec has been added (eg. symbolic
links).
So far, the new POSIX library has signal support, directory/file
operations and lots of stuff from unistd.h. The module names are:
System.Posix
The main dude, exports everything
System.Posix.Types
All the POSIX types, using the same naming scheme as
Foreign.C.Types, Eg. CUid, COff, etc. Many of these types
were previously exported by GHC.Posix.
Additionally exports the "nicer" names used by the old POSIX
library for compatibility (eg. ProcessID == CPid, FileMode ==
CMode, etc.)
All reasonable instances are derived for these types.
System.Posix.Signals
Signal support, contains most of which was in PosixProcPrim before.
The RTS interface to the signal handling support has been
rationalised slightly.
System.Posix.Directory
Directory support, most were in PosixFiles before.
System.Posix.Files
File operations, most were in PosixFiles before.
System.Posix.Unistd
(for want of a better name) Miscellaneous bits that mostly come
from the unistd.h header file. PosixProcEnv before.
The rest of the library should pan out like so:
System.Posix.IO
System.Posix.Error (maybe)
System.Posix.Process
System.Posix.Terminal
(I've no doubt broken Win32 support, but I'm checking the build at the moment).
Diffstat (limited to 'System/Posix/Directory.hsc')
-rw-r--r-- | System/Posix/Directory.hsc | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/System/Posix/Directory.hsc b/System/Posix/Directory.hsc new file mode 100644 index 0000000..a2a2ceb --- /dev/null +++ b/System/Posix/Directory.hsc @@ -0,0 +1,133 @@ +{-# OPTIONS -fffi #-} +----------------------------------------------------------------------------- +-- | +-- Module : System.Posix.Files +-- Copyright : (c) The University of Glasgow 2002 +-- License : BSD-style (see the file libraries/base/LICENSE) +-- +-- Maintainer : libraries@haskell.org +-- Stability : provisional +-- Portability : non-portable (requires POSIX) +-- +-- POSIX directory support +-- +----------------------------------------------------------------------------- + +module System.Posix.Directory ( + -- * Creating and removing directories + createDirectory, removeDirectory, + + -- * Reading directories + DirStream, + openDirStream, + readDirStream, + rewindDirStream, + closeDirStream, + DirStreamOffset, + tellDirStream, + seekDirStream, + + -- * The working dirctory + getWorkingDirectory, + changeWorkingDirectory, + changeWorkingDirectoryFd, + ) where + +import System.Posix.Types + +import GHC.Posix +import System.Directory hiding (createDirectory) +import Foreign +import Foreign.C + +createDirectory :: FilePath -> FileMode -> IO () +createDirectory name mode = + withCString name $ \s -> + throwErrnoIfMinus1_ "createDirectory" (c_mkdir s mode) + +foreign import ccall unsafe "mkdir" + c_mkdir :: CString -> CMode -> IO CInt + +newtype DirStream = DirStream (Ptr CDir) + +openDirStream :: FilePath -> IO DirStream +openDirStream name = + withCString name $ \s -> do + dirp <- throwErrnoIfNull "openDirStream" $ c_opendir s + return (DirStream dirp) + +readDirStream :: DirStream -> IO FilePath +readDirStream (DirStream dirp) = + alloca $ \ptr_dEnt -> loop ptr_dEnt + where + loop ptr_dEnt = do + resetErrno + r <- readdir dirp ptr_dEnt + if (r == 0) + then do dEnt <- peek ptr_dEnt + if (dEnt == nullPtr) + then return [] + else do + entry <- (d_name dEnt >>= peekCString) + freeDirEnt dEnt + return entry + else do errno <- getErrno + if (errno == eINTR) then loop ptr_dEnt else do + let (Errno eo) = errno + if (eo == end_of_dir) + then return [] + else throwErrno "readDirStream" + +foreign import ccall unsafe "__hscore_readdir" + readdir :: Ptr CDir -> Ptr (Ptr CDirent) -> IO CInt + +foreign import ccall unsafe "__hscore_free_dirent" + freeDirEnt :: Ptr CDirent -> IO () + +foreign import ccall unsafe "__hscore_end_of_dir" + end_of_dir :: CInt + +foreign import ccall unsafe "__hscore_d_name" + d_name :: Ptr CDirent -> IO CString + +rewindDirStream :: DirStream -> IO () +rewindDirStream (DirStream dirp) = c_rewinddir dirp + +closeDirStream :: DirStream -> IO () +closeDirStream (DirStream dirp) = do + throwErrnoIfMinus1_ "closeDirStream" (c_closedir dirp) + +newtype DirStreamOffset = DirStreamOffset CLong + +seekDirStream :: DirStream -> DirStreamOffset -> IO () +seekDirStream (DirStream dirp) (DirStreamOffset off) = + c_seekdir dirp off + +foreign import ccall unsafe "seekdir" + c_seekdir :: Ptr CDir -> CLong -> IO () + +tellDirStream :: DirStream -> IO DirStreamOffset +tellDirStream (DirStream dirp) = do + off <- c_telldir dirp + return (DirStreamOffset off) + +foreign import ccall unsafe "telldir" + c_telldir :: Ptr CDir -> IO CLong + +{- + Renamings of functionality provided via Directory interface, + kept around for b.wards compatibility and for having more POSIXy + names +-} +getWorkingDirectory :: IO FilePath +getWorkingDirectory = getCurrentDirectory + +changeWorkingDirectory :: FilePath -> IO () +changeWorkingDirectory name = setCurrentDirectory name + +changeWorkingDirectoryFd :: Fd -> IO () +changeWorkingDirectoryFd (Fd fd) = + throwErrnoIfMinus1_ "changeWorkingDirectoryFd" (c_fchdir fd) + +foreign import ccall unsafe "fchdir" + c_fchdir :: CInt -> IO CInt |