{-# OPTIONS_GHC -optc-DFUSE_USE_VERSION=22 #-}{-# INCLUDE <sys/statfs.h> #-}{-# INCLUDE <dirent.h> #-}{-# INCLUDE <fuse.h> #-}{-# INCLUDE <fcntl.h> #-}{-# LINE 1 "System/Posix/HFuse.hsc" #-}-----------------------------------------------------------------------------{-# LINE 2 "System/Posix/HFuse.hsc" #-}-- |-- Module : System.Posix.HFuse-- Copyright : (c) Jérémy Bobbio-- License : BSD-style---- Maintainer : jeremy.bobbio@etu.upmc.fr-- Stability : experimental-- Portability : GHC 6.8---- HFuse is a binding for the FUSE (Filesystem in USErspace) library.---- See <http://fuse.sourceforge.net/>---- This library allow new filesystem implementation as simple user-land-- programs.---- The binding tries to follow as much as possible current Haskell POSIX-- interface in "System.Posix.Files" and "System.Posix.Directory".---- FUSE uses POSIX thread, thus Haskell implementation needs to be linked-- against a threaded runtime system (eg. using the @threaded@ GHC option).-------------------------------------------------------------------------------moduleSystem.Posix.HFuse(-- * Using FUSE-- $intromoduleForeign.C.Error,FuseOperations(..),defaultFuseOps,fuseMain-- :: FuseOperations -> (Exception -> IO Errno) -> IO (),defaultExceptionHandler-- :: Exception -> IO Errno-- * Operations datatypes,FileStat(..),EntryType(..),FileSystemStats(..),SyncType(..)-- * FUSE Context,getFuseContext-- :: IO FuseContext,FuseContext(fuseCtxUserID,fuseCtxGroupID,fuseCtxProcessID)-- * File modes,entryTypeToFileMode-- :: EntryType -> FileMode,OpenMode(..),OpenFileFlags(..),intersectFileModes-- :: FileMode,unionFileModes-- :: FileMode)whereimportPreludehiding(Read)importControl.Exception(Exception,handle)importForeignimportForeign.CimportForeign.C.ErrorimportForeign.MarshalimportSystem.Environment(getProgName,getArgs)importSystem.IO(hPutStrLn,stderr)importSystem.Posix.TypesimportSystem.Posix.Files(accessModes,intersectFileModes,unionFileModes)importSystem.Posix.IO(OpenMode(..),OpenFileFlags(..))-- TODO: FileMode -> Permissions-- TODO: Arguments !-- TODO: implement binding to fuse_invalidate-- TODO: bind fuse_*xattr{-# LINE 70 "System/Posix/HFuse.hsc" #-}{-# LINE 72 "System/Posix/HFuse.hsc" #-}{-# LINE 73 "System/Posix/HFuse.hsc" #-}{-# LINE 74 "System/Posix/HFuse.hsc" #-}{-# LINE 75 "System/Posix/HFuse.hsc" #-}{- $intro
'FuseOperations' contains a field for each filesystem operations that can be called
by FUSE. Think like if you were implementing a file system inside the Linux kernel.
Each actions must return a POSIX error code, also called 'Errno' reflecting
operation relult. For actions not using 'Either', you should return 'eOK' in case
of success.
Read and writes are done with Haskell 'String' type. Even if this representation
is known to have drawbacks, the binding try to be coherent with current
Haskell libraries.
-}{- All operations should return the negated error value (-errno) on
error.
-}-- | Used by 'fuseGetFileStat'.dataFileStat=FileStat{statEntryType::EntryType,statFileMode::FileMode,statLinkCount::LinkCount,statFileOwner::UserID,statFileGroup::GroupID,statSpecialDeviceID::DeviceID,statFileSize::FileOffset,statBlocks::Integer,statAccessTime::EpochTime,statModificationTime::EpochTime,statStatusChangeTime::EpochTime}{- getattr() doesn't need to fill in the following fields:
st_ino
st_dev
st_blksize
-}{- readlink() should fill the buffer with a null terminated string. The
buffer size argument includes the space for the terminating null
character. If the linkname is too long to fit in the buffer, it should
be truncated. The return value should be 0 for success.
-}-- | Used by 'fuseGetDirectoryContents' implementation to specify the type of-- a directory entry.dataEntryType=Unknown-- ^ Unknown entry type|NamedPipe|CharacterSpecial|Directory|BlockSpecial|RegularFile|SymbolicLink|SocketentryTypeToDT::EntryType->IntentryTypeToDTUnknown=(0){-# LINE 134 "System/Posix/HFuse.hsc" #-}entryTypeToDTNamedPipe=(1){-# LINE 135 "System/Posix/HFuse.hsc" #-}entryTypeToDTCharacterSpecial=(2){-# LINE 136 "System/Posix/HFuse.hsc" #-}entryTypeToDTDirectory=(4){-# LINE 137 "System/Posix/HFuse.hsc" #-}entryTypeToDTBlockSpecial=(6){-# LINE 138 "System/Posix/HFuse.hsc" #-}entryTypeToDTRegularFile=(8){-# LINE 139 "System/Posix/HFuse.hsc" #-}entryTypeToDTSymbolicLink=(10){-# LINE 140 "System/Posix/HFuse.hsc" #-}entryTypeToDTSocket=(12){-# LINE 141 "System/Posix/HFuse.hsc" #-}fileTypeModes::FileModefileTypeModes=(61440){-# LINE 144 "System/Posix/HFuse.hsc" #-}blockSpecialMode::FileModeblockSpecialMode=(24576){-# LINE 147 "System/Posix/HFuse.hsc" #-}characterSpecialMode::FileModecharacterSpecialMode=(8192){-# LINE 150 "System/Posix/HFuse.hsc" #-}namedPipeMode::FileModenamedPipeMode=(4096){-# LINE 153 "System/Posix/HFuse.hsc" #-}regularFileMode::FileModeregularFileMode=(32768){-# LINE 156 "System/Posix/HFuse.hsc" #-}directoryMode::FileModedirectoryMode=(16384){-# LINE 159 "System/Posix/HFuse.hsc" #-}symbolicLinkMode::FileModesymbolicLinkMode=(40960){-# LINE 162 "System/Posix/HFuse.hsc" #-}socketMode::FileModesocketMode=(49152){-# LINE 165 "System/Posix/HFuse.hsc" #-}-- | Converts an 'EntryType' into the corresponding POSIX 'FileMode'.entryTypeToFileMode::EntryType->FileModeentryTypeToFileModeUnknown=0entryTypeToFileModeNamedPipe=namedPipeModeentryTypeToFileModeCharacterSpecial=characterSpecialModeentryTypeToFileModeDirectory=directoryModeentryTypeToFileModeBlockSpecial=blockSpecialModeentryTypeToFileModeRegularFile=regularFileModeentryTypeToFileModeSymbolicLink=symbolicLinkModeentryTypeToFileModeSocket=socketModefileModeToEntryType::FileMode->EntryTypefileModeToEntryTypemode|fileType==namedPipeMode=NamedPipe|fileType==characterSpecialMode=CharacterSpecial|fileType==directoryMode=Directory|fileType==blockSpecialMode=BlockSpecial|fileType==regularFileMode=RegularFile|fileType==symbolicLinkMode=SymbolicLink|fileType==socketMode=SocketwherefileType=mode.&.(61440){-# LINE 187 "System/Posix/HFuse.hsc" #-}{- getdir() is the opendir(), readdir(), ..., closedir() sequence
in one call. For each directory entry the filldir parameter should
be called.
-}{-
There is no create() operation, mknod() will be called for
creation of all non directory, non symlink nodes.
-}{- open() should not return a filehandle, but 0 on success. No
creation, or trunctation flags (O_CREAT, O_EXCL, O_TRUNC) will be
passed to open(). Open should only check if the operation is
permitted for the given flags.
-}{- read(), write() are not passed a filehandle, but rather a
pathname. The offset of the read and write is passed as the last
argument, like the pread() and pwrite() system calls. (NOTE:
read() should always return the number of bytes requested, except
at end of file)
TODO: String type was used to mimic System.Posix.IO but it should change
after inclusion of better I/O system in Haskell libraries.
-}-- | Type used by the 'fuseGetFileSystemStats'.dataFileSystemStats=FileSystemStats{fsStatBlockSize::Integer-- ^ Optimal transfer block size. FUSE default is 512.,fsStatBlockCount::Integer-- ^ Total data blocks in file system.,fsStatBlocksFree::Integer-- ^ Free blocks in file system.,fsStatBlocksAvailable::Integer-- ^ Free blocks available to non-superusers.,fsStatFileCount::Integer-- ^ Total file nodes in file system.,fsStatFilesFree::Integer-- ^ Free file nodes in file system.,fsStatMaxNameLength::Integer-- ^ Maximum length of filenames. FUSE default is 255.}{- release() is called when an open file has:
1) all file descriptors closed
2)
all memory mappings unmapped
This call need only be implemented if this information is required,
otherwise set this function to NULL.
TODO: Find out what these "flags" are (Int here).
-}-- | Used by 'fuseSynchronizeFile'.dataSyncType=FullSync-- ^ Synchronize all in-core parts of a file to disk: file content and-- metadata.|DataSync-- ^ Synchronize only the file content.deriving(Eq,Enum){- fsync() has a boolean 'datasync' parameter which if TRUE then do
an fdatasync() operation.
-}-- | Returned by 'getFuseContext'.dataFuseContext=FuseContext{fuseCtxUserID::UserID,fuseCtxGroupID::GroupID,fuseCtxProcessID::ProcessID}-- | Returns the context of the program doing the current FUSE call.getFuseContext::IOFuseContextgetFuseContext=dopCtx<-fuse_get_contextuserID<-((\hsc_ptr->peekByteOffhsc_ptr4))pCtx{-# LINE 268 "System/Posix/HFuse.hsc" #-}groupID<-((\hsc_ptr->peekByteOffhsc_ptr8))pCtx{-# LINE 269 "System/Posix/HFuse.hsc" #-}processID<-((\hsc_ptr->peekByteOffhsc_ptr12))pCtx{-# LINE 270 "System/Posix/HFuse.hsc" #-}return$FuseContext{fuseCtxUserID=userID,fuseCtxGroupID=groupID,fuseCtxProcessID=processID}-- | This record, given to 'fuseMain', binds each required file system operations.---- Each field is named against 'System.Posix' names. Matching Linux system calls-- are also given as a reference.---- * 'fuseGetFileStat' implements-- 'System.Posix.Files.getSymbolicLinkStatus' operation (POSIX @lstat(2)@).---- * 'fuseReadSymbolicLink' implements-- 'System.Posix.Files.readSymbolicLink' operation (POSIX @readlink(2)@).-- The returned 'FilePath' might be truncated depending on caller-- buffer size.---- * 'fuseGetDirectoryContents' implements-- 'System.Directory.getDirectoryContents' (POSIX @readddir(2)@).---- * 'fuseCreateDevice' implements 'System.Posix.Files.createDevice'-- (POSIX @mknod(2)@).-- This function will also be called for regular file creation.---- * 'fuseCreateDirectory' implements 'System.Posix.Directory.createDirectory'-- (POSIX @mkdir(2)@).---- * 'fuseRemoveLink' implements 'System.Posix.Files.removeLink'-- (POSIX @unlink(2)@).---- * 'fuseRemoveDirectory' implements 'System.Posix.Directory.removeDirectory'-- (POSIX @rmdir(2)@).---- * 'fuseCreateSymbolicLink' implements-- 'System.Posix.Files.createSymbolicLink' (POSIX @symlink(2)@).---- * 'fuseRename' implements 'System.Posix.Files.rename' (POSIX @rename(2)@).---- * 'fuseCreateLink' implements 'System.Posix.Files.createLink'-- (POSIX @link(2)@).---- * 'fuseSetFileMode' implements 'System.Posix.Files.setFileMode'-- (POSIX @chmod(2)@).---- * 'fuseSetOwnerAndGroup' implements 'System.Posix.Files.setOwnerAndGroup'-- (POSIX @chown(2)@).---- * 'fuseSetFileSize' implements 'System.Posix.Files.setFileSize'-- (POSIX @truncate(2)@).---- * 'fuseSetFileTimes' implements 'System.Posix.Files.setFileTimes'-- (POSIX @utime(2)@).---- * 'fuseOpen' implements 'System.Posix.Files.openFd'-- (POSIX @open(2)@), but this does not actually returns a file handle-- but 'eOK' if the operation is permitted with the given flags.-- No creation, exclusive access or truncating flags will be passed.---- * 'fuseRead' implements Unix98 @pread(2)@. It differs-- from 'System.Posix.Files.fdRead' by the explicit 'FileOffset' argument.---- * 'fuseWrite' implements Unix98 @pwrite(2)@. It differs-- from 'System.Posix.Files.fdWrite' by the explicit 'FileOffset' argument.---- * 'fuseGetFileSystemStats' implements @statfs(2)@.---- * 'fuseFlush' is called when @close(2)@ has been called on an open file.-- Note: this does not mean that the file is released. This function may be-- called more than once for each @open(2)@. The return value is passed on-- to the @close(2)@ system call.---- * 'fuseRelease' is called when an open file has all file descriptors closed-- and all memory mappings unmapped. For every @open@ call there will be-- exactly one @release@ call with the same flags. It is possible to have-- a file opened more than once, in which case only the last release will-- mean, that no more reads or writes will happen on the file.---- * 'fuseSynchronizeFile' implements @fsync(2)@.--dataFuseOperations=FuseOperations{fuseGetFileStat::FilePath->IO(EitherErrnoFileStat),fuseReadSymbolicLink::FilePath->IO(EitherErrnoFilePath),fuseGetDirectoryContents::FilePath->IO(EitherErrno[(FilePath,EntryType)]),fuseCreateDevice::FilePath->EntryType->FileMode->DeviceID->IOErrno,fuseCreateDirectory::FilePath->FileMode->IOErrno,fuseRemoveLink::FilePath->IOErrno,fuseRemoveDirectory::FilePath->IOErrno,fuseCreateSymbolicLink::FilePath->FilePath->IOErrno,fuseRename::FilePath->FilePath->IOErrno,fuseCreateLink::FilePath->FilePath->IOErrno,fuseSetFileMode::FilePath->FileMode->IOErrno,fuseSetOwnerAndGroup::FilePath->UserID->GroupID->IOErrno,fuseSetFileSize::FilePath->FileOffset->IOErrno,fuseSetFileTimes::FilePath->EpochTime->EpochTime->IOErrno,fuseOpen::FilePath->OpenMode->OpenFileFlags->IOErrno,fuseRead::FilePath->ByteCount->FileOffset->IO(EitherErrno(String,ByteCount)),fuseWrite::FilePath->String->FileOffset->IO(EitherErrnoByteCount),fuseGetFileSystemStats::String->IO(EitherErrnoFileSystemStats),fuseFlush::FilePath->IOErrno,fuseRelease::FilePath->Int->IO(),fuseSynchronizeFile::FilePath->SyncType->IOErrno,fuseOpenDirectory::FilePath->IOErrno,fuseReleaseDirectory::FilePath->IOErrno,fuseSynchronizeDirectory::FilePath->SyncType->IOErrno,fuseInit::IO(),fuseDestroy::IO()}-- |Empty / default versions of the FUSE operations.defaultFuseOps::FuseOperationsdefaultFuseOps=FuseOperations{fuseGetFileStat=\_->return(LefteNOSYS),fuseReadSymbolicLink=\_->return(LefteNOSYS),fuseGetDirectoryContents=\_->return(LefteNOSYS),fuseCreateDevice=\____->returneNOSYS,fuseCreateDirectory=\__->returneNOSYS,fuseRemoveLink=\_->returneNOSYS,fuseRemoveDirectory=\_->returneNOSYS,fuseCreateSymbolicLink=\__->returneNOSYS,fuseRename=\__->returneNOSYS,fuseCreateLink=\__->returneNOSYS,fuseSetFileMode=\__->returneNOSYS,fuseSetOwnerAndGroup=\___->returneNOSYS,fuseSetFileSize=\__->returneNOSYS,fuseSetFileTimes=\___->returneNOSYS,fuseOpen=\___->returneNOSYS,fuseRead=\___->return(LefteNOSYS),fuseWrite=\___->return(LefteNOSYS),fuseGetFileSystemStats=\_->return(LefteNOSYS),fuseFlush=\_->returneOK,fuseRelease=\__->return(),fuseSynchronizeFile=\__->returneNOSYS,fuseOpenDirectory=\_->returneNOSYS,fuseReleaseDirectory=\_->returneNOSYS,fuseSynchronizeDirectory=\__->returneNOSYS,fuseInit=return(),fuseDestroy=return()}-- | Main function of FUSE.-- This is all that has to be called from the @main@ function. On top of-- the 'FuseOperations' record with filesystem implementation, you must give-- an exception handler converting Haskell exceptions to 'Errno'.---- This function does the following:---- * parses command line options (@-d@, @-s@ and @-h@) ;---- * passes all options after @--@ to the fusermount program ;---- * mounts the filesystem by calling @fusermount@ ;---- * installs signal handlers for 'System.Posix.Signals.keyboardSignal',-- 'System.Posix.Signals.lostConnection',-- 'System.Posix.Signals.softwareTermination' and-- 'System.Posix.Signals.openEndedPipe' ;---- * registers an exit handler to unmount the filesystem on program exit ;---- * registers the operations ;---- * calls FUSE event loop.fuseMain::FuseOperations->(Exception->IOErrno)->IO()fuseMainopshandler=allocaBytes((124))$\pOps->do{-# LINE 441 "System/Posix/HFuse.hsc" #-}mkGetAttrwrapGetAttr>>=((\hsc_ptr->pokeByteOffhsc_ptr0))pOps{-# LINE 442 "System/Posix/HFuse.hsc" #-}mkReadLinkwrapReadLink>>=((\hsc_ptr->pokeByteOffhsc_ptr4))pOps{-# LINE 443 "System/Posix/HFuse.hsc" #-}-- FIXME: getdir is deprecatedmkGetDirwrapGetDir>>=((\hsc_ptr->pokeByteOffhsc_ptr8))pOps{-# LINE 445 "System/Posix/HFuse.hsc" #-}mkMkNodwrapMkNod>>=((\hsc_ptr->pokeByteOffhsc_ptr12))pOps{-# LINE 446 "System/Posix/HFuse.hsc" #-}mkMkDirwrapMkDir>>=((\hsc_ptr->pokeByteOffhsc_ptr16))pOps{-# LINE 447 "System/Posix/HFuse.hsc" #-}mkUnlinkwrapUnlink>>=((\hsc_ptr->pokeByteOffhsc_ptr20))pOps{-# LINE 448 "System/Posix/HFuse.hsc" #-}mkRmDirwrapRmDir>>=((\hsc_ptr->pokeByteOffhsc_ptr24))pOps{-# LINE 449 "System/Posix/HFuse.hsc" #-}mkSymLinkwrapSymLink>>=((\hsc_ptr->pokeByteOffhsc_ptr28))pOps{-# LINE 450 "System/Posix/HFuse.hsc" #-}mkRenamewrapRename>>=((\hsc_ptr->pokeByteOffhsc_ptr32))pOps{-# LINE 451 "System/Posix/HFuse.hsc" #-}mkLinkwrapLink>>=((\hsc_ptr->pokeByteOffhsc_ptr36))pOps{-# LINE 452 "System/Posix/HFuse.hsc" #-}mkChModwrapChMod>>=((\hsc_ptr->pokeByteOffhsc_ptr40))pOps{-# LINE 453 "System/Posix/HFuse.hsc" #-}mkChOwnwrapChOwn>>=((\hsc_ptr->pokeByteOffhsc_ptr44))pOps{-# LINE 454 "System/Posix/HFuse.hsc" #-}mkTruncatewrapTruncate>>=((\hsc_ptr->pokeByteOffhsc_ptr48))pOps{-# LINE 455 "System/Posix/HFuse.hsc" #-}mkUTimewrapUTime>>=((\hsc_ptr->pokeByteOffhsc_ptr52))pOps{-# LINE 456 "System/Posix/HFuse.hsc" #-}mkOpenwrapOpen>>=((\hsc_ptr->pokeByteOffhsc_ptr56))pOps{-# LINE 457 "System/Posix/HFuse.hsc" #-}mkReadwrapRead>>=((\hsc_ptr->pokeByteOffhsc_ptr60))pOps{-# LINE 458 "System/Posix/HFuse.hsc" #-}mkWritewrapWrite>>=((\hsc_ptr->pokeByteOffhsc_ptr64))pOps{-# LINE 459 "System/Posix/HFuse.hsc" #-}mkStatFSwrapStatFS>>=((\hsc_ptr->pokeByteOffhsc_ptr68))pOps{-# LINE 460 "System/Posix/HFuse.hsc" #-}mkFlushwrapFlush>>=((\hsc_ptr->pokeByteOffhsc_ptr72))pOps{-# LINE 461 "System/Posix/HFuse.hsc" #-}mkReleasewrapRelease>>=((\hsc_ptr->pokeByteOffhsc_ptr76))pOps{-# LINE 462 "System/Posix/HFuse.hsc" #-}mkFSyncwrapFSync>>=((\hsc_ptr->pokeByteOffhsc_ptr80))pOps{-# LINE 463 "System/Posix/HFuse.hsc" #-}-- TODO: Implement these((\hsc_ptr->pokeByteOffhsc_ptr84))pOpsnullPtr{-# LINE 465 "System/Posix/HFuse.hsc" #-}((\hsc_ptr->pokeByteOffhsc_ptr88))pOpsnullPtr{-# LINE 466 "System/Posix/HFuse.hsc" #-}((\hsc_ptr->pokeByteOffhsc_ptr92))pOpsnullPtr{-# LINE 467 "System/Posix/HFuse.hsc" #-}((\hsc_ptr->pokeByteOffhsc_ptr96))pOpsnullPtr{-# LINE 468 "System/Posix/HFuse.hsc" #-}mkOpenDirwrapOpenDir>>=((\hsc_ptr->pokeByteOffhsc_ptr100))pOps{-# LINE 469 "System/Posix/HFuse.hsc" #-}-- TODO: Implement mkReadDir-- mkReadDir wrapReadDir >>= (#poke struct fuse_operations, readdir) pOps((\hsc_ptr->pokeByteOffhsc_ptr104))pOpsnullPtr{-# LINE 472 "System/Posix/HFuse.hsc" #-}mkReleaseDirwrapReleaseDir>>=((\hsc_ptr->pokeByteOffhsc_ptr108))pOps{-# LINE 473 "System/Posix/HFuse.hsc" #-}mkFSyncDirwrapFSyncDir>>=((\hsc_ptr->pokeByteOffhsc_ptr112))pOps{-# LINE 474 "System/Posix/HFuse.hsc" #-}mkInitwrapInit>>=((\hsc_ptr->pokeByteOffhsc_ptr116))pOps{-# LINE 475 "System/Posix/HFuse.hsc" #-}mkDestroywrapDestroy>>=((\hsc_ptr->pokeByteOffhsc_ptr120))pOps{-# LINE 476 "System/Posix/HFuse.hsc" #-}prog<-getProgNameargs<-getArgsletallArgs=(prog:args)argc=lengthallArgswithManywithCStringallArgs$\pAddrs->withArraypAddrs$\pArgv->dofuse_main_realargcpArgvpOps((124)){-# LINE 483 "System/Posix/HFuse.hsc" #-}wherefuseHandler::Exception->IOCIntfuseHandlere=handlere>>=return.unErrnowrapGetAttr::CGetAttrwrapGetAttrpFilePathpStat=handlefuseHandler$dofilePath<-peekCStringpFilePatheitherFileStat<-(fuseGetFileStatops)filePathcaseeitherFileStatofLeft(Errnoerrno)->return(-errno)Rightstat->do((\hsc_ptr->pokeByteOffhsc_ptr16))pStat{-# LINE 493 "System/Posix/HFuse.hsc" #-}(entryTypeToFileMode(statEntryTypestat)`unionFileModes`(statFileModestat`intersectFileModes`accessModes))((\hsc_ptr->pokeByteOffhsc_ptr20))pStat(statLinkCountstat){-# LINE 497 "System/Posix/HFuse.hsc" #-}((\hsc_ptr->pokeByteOffhsc_ptr24))pStat(statFileOwnerstat){-# LINE 498 "System/Posix/HFuse.hsc" #-}((\hsc_ptr->pokeByteOffhsc_ptr28))pStat(statFileGroupstat){-# LINE 499 "System/Posix/HFuse.hsc" #-}((\hsc_ptr->pokeByteOffhsc_ptr32))pStat{-# LINE 500 "System/Posix/HFuse.hsc" #-}(statSpecialDeviceIDstat)((\hsc_ptr->pokeByteOffhsc_ptr44))pStat(statFileSizestat){-# LINE 502 "System/Posix/HFuse.hsc" #-}((\hsc_ptr->pokeByteOffhsc_ptr56))pStat{-# LINE 503 "System/Posix/HFuse.hsc" #-}(fromIntegral(statBlocksstat)::(Int64)){-# LINE 504 "System/Posix/HFuse.hsc" #-}((\hsc_ptr->pokeByteOffhsc_ptr64))pStat(statAccessTimestat){-# LINE 505 "System/Posix/HFuse.hsc" #-}((\hsc_ptr->pokeByteOffhsc_ptr72))pStat{-# LINE 506 "System/Posix/HFuse.hsc" #-}(statModificationTimestat)((\hsc_ptr->pokeByteOffhsc_ptr80))pStat{-# LINE 508 "System/Posix/HFuse.hsc" #-}(statStatusChangeTimestat)returnokErrnowrapReadLink::CReadLinkwrapReadLinkpFilePathpBufbufSize=handlefuseHandler$dofilePath<-peekCStringpFilePathreturn(-unErrnoeNOSYS)eitherTarget<-(fuseReadSymbolicLinkops)filePathcaseeitherTargetofLeft(Errnoerrno)->return(-errno)Righttarget->dopokeCStringLen0(pBuf,(fromIntegralbufSize))targetreturnokErrnowrapGetDir::CGetDirwrapGetDirpFilePathpDirHandlepDirFil=handlefuseHandler$dofilePath<-peekCStringpFilePathletfiller(entryFilePath,entryType)=withCStringentryFilePath$\pEntryFilePath->(mkDirFilpDirFil)pDirHandlepEntryFilePath(entryTypeToDTentryType)>>=return.ErrnoeitherContents<-(fuseGetDirectoryContentsops)filePathcaseeitherContentsofLeft(Errnoerrno)->return(-errno)Rightcontents->domapM_fillercontentsreturnokErrnowrapMkNod::CMkNodwrapMkNodpFilePathmodedev=handlefuseHandler$dofilePath<-peekCStringpFilePath(Errnoerrno)<-(fuseCreateDeviceops)filePath(fileModeToEntryTypemode)modedevreturn(-errno)wrapMkDir::CMkDirwrapMkDirpFilePathmode=handlefuseHandler$dofilePath<-peekCStringpFilePath(Errnoerrno)<-(fuseCreateDirectoryops)filePathmodereturn(-errno)wrapUnlink::CUnlinkwrapUnlinkpFilePath=handlefuseHandler$dofilePath<-peekCStringpFilePath(Errnoerrno)<-(fuseRemoveLinkops)filePathreturn(-errno)wrapRmDir::CRmDirwrapRmDirpFilePath=handlefuseHandler$dofilePath<-peekCStringpFilePath(Errnoerrno)<-(fuseRemoveDirectoryops)filePathreturn(-errno)wrapSymLink::CSymLinkwrapSymLinkpSourcepDestination=handlefuseHandler$dosource<-peekCStringpSourcedestination<-peekCStringpDestination(Errnoerrno)<-(fuseCreateSymbolicLinkops)sourcedestinationreturn(-errno)wrapRename::CRenamewrapRenamepOldpNew=handlefuseHandler$doold<-peekCStringpOldnew<-peekCStringpNew(Errnoerrno)<-(fuseRenameops)oldnewreturn(-errno)wrapLink::CLinkwrapLinkpSourcepDestination=handlefuseHandler$dosource<-peekCStringpSourcedestination<-peekCStringpDestination(Errnoerrno)<-(fuseCreateLinkops)sourcedestinationreturn(-errno)wrapChMod::CChModwrapChModpFilePathmode=handlefuseHandler$dofilePath<-peekCStringpFilePath(Errnoerrno)<-(fuseSetFileModeops)filePathmodereturn(-errno)wrapChOwn::CChOwnwrapChOwnpFilePathuidgid=handlefuseHandler$dofilePath<-peekCStringpFilePath(Errnoerrno)<-(fuseSetOwnerAndGroupops)filePathuidgidreturn(-errno)wrapTruncate::CTruncatewrapTruncatepFilePathoff=handlefuseHandler$dofilePath<-peekCStringpFilePath(Errnoerrno)<-(fuseSetFileSizeops)filePathoffreturn(-errno)wrapUTime::CUTimewrapUTimepFilePathpUTimBuf=handlefuseHandler$dofilePath<-peekCStringpFilePathaccessTime<-((\hsc_ptr->peekByteOffhsc_ptr0))pUTimBuf{-# LINE 591 "System/Posix/HFuse.hsc" #-}modificationTime<-((\hsc_ptr->peekByteOffhsc_ptr4))pUTimBuf{-# LINE 592 "System/Posix/HFuse.hsc" #-}(Errnoerrno)<-(fuseSetFileTimesops)filePathaccessTimemodificationTimereturn(-errno)wrapOpen::COpenwrapOpenpFilePathpFuseFileInfo=handlefuseHandler$dofilePath<-peekCStringpFilePath(flags::CInt)<-((\hsc_ptr->peekByteOffhsc_ptr0))pFuseFileInfo{-# LINE 599 "System/Posix/HFuse.hsc" #-}letappend=(1024).&.flags==(1024){-# LINE 600 "System/Posix/HFuse.hsc" #-}noctty=(256).&.flags==(256){-# LINE 601 "System/Posix/HFuse.hsc" #-}nonBlock=(2048).&.flags==(2048){-# LINE 602 "System/Posix/HFuse.hsc" #-}how|(2).&.flags==(2)=ReadWrite{-# LINE 603 "System/Posix/HFuse.hsc" #-}|(1).&.flags==(1)=WriteOnly{-# LINE 604 "System/Posix/HFuse.hsc" #-}|otherwise=ReadOnlyopenFileFlags=OpenFileFlags{append=append,exclusive=False,noctty=noctty,nonBlock=nonBlock,trunc=False}(Errnoerrno)<-(fuseOpenops)filePathhowopenFileFlagsreturn(-errno)wrapRead::CReadwrapReadpFilePathpBufbufSizoffpFuseFileInfo=handlefuseHandler$dofilePath<-peekCStringpFilePatheitherRead<-(fuseReadops)filePathbufSizoffcaseeitherReadofLeft(Errnoerrno)->return(-errno)Right(bytes,byteCount)->dopokeCStringLen(pBuf,fromIntegralbyteCount)bytesreturn(fromIntegralbyteCount)wrapWrite::CWritewrapWritepFilePathpBufbufSizoffpFuseFileInfo=handlefuseHandler$dofilePath<-peekCStringpFilePathbuf<-peekCStringLen(pBuf,fromIntegralbufSiz)eitherBytes<-(fuseWriteops)filePathbufoffcaseeitherBytesofLeft(Errnoerrno)->return(-errno)Rightbytes->return(fromIntegralbytes)wrapStatFS::CStatFSwrapStatFSpStrpStatFS=handlefuseHandler$dostr<-peekCStringpStreitherStatFS<-(fuseGetFileSystemStatsops)strcaseeitherStatFSofLeft(Errnoerrno)->return(-errno)Rightstat->do((\hsc_ptr->pokeByteOffhsc_ptr4))pStatFS{-# LINE 638 "System/Posix/HFuse.hsc" #-}(fromIntegral(fsStatBlockSizestat)::(Int32)){-# LINE 639 "System/Posix/HFuse.hsc" #-}((\hsc_ptr->pokeByteOffhsc_ptr8))pStatFS{-# LINE 640 "System/Posix/HFuse.hsc" #-}(fromIntegral(fsStatBlockCountstat)::(Int32)){-# LINE 641 "System/Posix/HFuse.hsc" #-}((\hsc_ptr->pokeByteOffhsc_ptr16))pStatFS{-# LINE 642 "System/Posix/HFuse.hsc" #-}(fromIntegral(fsStatBlocksFreestat)::(Int32)){-# LINE 643 "System/Posix/HFuse.hsc" #-}((\hsc_ptr->pokeByteOffhsc_ptr24))pStatFS{-# LINE 644 "System/Posix/HFuse.hsc" #-}(fromIntegral(fsStatBlocksAvailablestat)::(Int32)){-# LINE 646 "System/Posix/HFuse.hsc" #-}((\hsc_ptr->pokeByteOffhsc_ptr32))pStatFS{-# LINE 647 "System/Posix/HFuse.hsc" #-}(fromIntegral(fsStatFileCountstat)::(Int32)){-# LINE 648 "System/Posix/HFuse.hsc" #-}((\hsc_ptr->pokeByteOffhsc_ptr40))pStatFS{-# LINE 649 "System/Posix/HFuse.hsc" #-}(fromIntegral(fsStatFilesFreestat)::(Int32)){-# LINE 650 "System/Posix/HFuse.hsc" #-}((\hsc_ptr->pokeByteOffhsc_ptr56))pStatFS{-# LINE 651 "System/Posix/HFuse.hsc" #-}(fromIntegral(fsStatMaxNameLengthstat)::(Int32)){-# LINE 652 "System/Posix/HFuse.hsc" #-}return0wrapFlush::CFlushwrapFlushpFilePathpFuseFileInfo=handlefuseHandler$dofilePath<-peekCStringpFilePath(Errnoerrno)<-(fuseFlushops)filePathreturn(-errno)wrapRelease::CReleasewrapReleasepFilePathpFuseFileInfo=handlefuseHandler$dofilePath<-peekCStringpFilePathflags<-((\hsc_ptr->peekByteOffhsc_ptr0))pFuseFileInfo{-# LINE 662 "System/Posix/HFuse.hsc" #-}(fuseReleaseops)filePathflagsreturn0wrapFSync::CFSyncwrapFSyncpFilePathisFullSyncpFuseFileInfo=handlefuseHandler$dofilePath<-peekCStringpFilePath(Errnoerrno)<-(fuseSynchronizeFileops)filePath(toEnumisFullSync)return(-errno)wrapOpenDir::COpenDirwrapOpenDirpFilePathpFuseFileInfo=handlefuseHandler$dofilePath<-peekCStringpFilePath-- XXX: Should we pass flags from pFuseFileInfo?(Errnoerrno)<-(fuseOpenDirectoryops)filePathreturn(-errno)-- TODO: wrapReadDirwrapReleaseDir::CReleaseDirwrapReleaseDirpFilePathpFuseFileInfo=handlefuseHandler$dofilePath<-peekCStringpFilePath(Errnoerrno)<-(fuseReleaseDirectoryops)filePathreturn(-errno)wrapFSyncDir::CFSyncDirwrapFSyncDirpFilePathisFullSyncpFuseFileInfo=handlefuseHandler$dofilePath<-peekCStringpFilePath(Errnoerrno)<-(fuseSynchronizeDirectoryops)filePath(toEnumisFullSync)return(-errno)wrapInit::CInitwrapInit=handle(\e->hPutStrLnstderr(showe)>>returnnullPtr)$dofuseInitopsreturnnullPtrwrapDestroy::CDestroywrapDestroy_=handle(\e->hPutStrLnstderr(showe))$dofuseDestroyops-- | Default exception handler.-- Print the exception on error output and returns 'eFAULT'.defaultExceptionHandler::(Exception->IOErrno)defaultExceptionHandlere=hPutStrLnstderr(showe)>>returneFAULT------------------------------------------------------------------------------- Miscelaneous utilitiesunErrno::Errno->CIntunErrno(Errnoerrno)=errnookErrno::CIntokErrno=0pokeCStringLen::CStringLen->String->IO()pokeCStringLen(pBuf,bufSize)src=pokeArraypBuf$takebufSize$mapcastCharToCCharsrcpokeCStringLen0::CStringLen->String->IO()pokeCStringLen0(pBuf,bufSize)src=pokeArray00pBuf$take(bufSize-1)$mapcastCharToCCharsrc------------------------------------------------------------------------------- C land----- exported C called from Haskell---dataCFuseOperationsforeignimportccallthreadsafe"fuse.h fuse_main_real"fuse_main_real::Int->PtrCString->PtrCFuseOperations->CSize->IO()dataStructFuseforeignimportccallthreadsafe"fuse.h fuse_get_context"fuse_get_context::IO(PtrStructFuse)----- dynamic Haskell called from C---dataCFuseFileInfo-- struct fuse_file_infodataCStat-- struct stattypeCGetAttr=CString->PtrCStat->IOCIntforeignimportccallthreadsafe"wrapper"mkGetAttr::CGetAttr->IO(FunPtrCGetAttr)typeCReadLink=CString->CString->CSize->IOCIntforeignimportccallthreadsafe"wrapper"mkReadLink::CReadLink->IO(FunPtrCReadLink)typeCGetDir=CString->PtrCDirHandle->FunPtrCDirFil->IOCIntforeignimportccallthreadsafe"wrapper"mkGetDir::CGetDir->IO(FunPtrCGetDir)typeCMkNod=CString->CMode->CDev->IOCIntforeignimportccallthreadsafe"wrapper"mkMkNod::CMkNod->IO(FunPtrCMkNod)typeCMkDir=CString->CMode->IOCIntforeignimportccallthreadsafe"wrapper"mkMkDir::CMkDir->IO(FunPtrCMkDir)typeCUnlink=CString->IOCIntforeignimportccallthreadsafe"wrapper"mkUnlink::CUnlink->IO(FunPtrCUnlink)typeCRmDir=CString->IOCIntforeignimportccallthreadsafe"wrapper"mkRmDir::CRmDir->IO(FunPtrCRmDir)typeCSymLink=CString->CString->IOCIntforeignimportccallthreadsafe"wrapper"mkSymLink::CSymLink->IO(FunPtrCSymLink)typeCRename=CString->CString->IOCIntforeignimportccallthreadsafe"wrapper"mkRename::CRename->IO(FunPtrCRename)typeCLink=CString->CString->IOCIntforeignimportccallthreadsafe"wrapper"mkLink::CLink->IO(FunPtrCLink)typeCChMod=CString->CMode->IOCIntforeignimportccallthreadsafe"wrapper"mkChMod::CChMod->IO(FunPtrCChMod)typeCChOwn=CString->CUid->CGid->IOCIntforeignimportccallthreadsafe"wrapper"mkChOwn::CChOwn->IO(FunPtrCChOwn)typeCTruncate=CString->COff->IOCIntforeignimportccallthreadsafe"wrapper"mkTruncate::CTruncate->IO(FunPtrCTruncate)dataCUTimBuf-- struct utimbuftypeCUTime=CString->PtrCUTimBuf->IOCIntforeignimportccallthreadsafe"wrapper"mkUTime::CUTime->IO(FunPtrCUTime)typeCOpen=CString->PtrCFuseFileInfo->IOCIntforeignimportccallthreadsafe"wrapper"mkOpen::COpen->IO(FunPtrCOpen)typeCRead=CString->CString->CSize->COff->PtrCFuseFileInfo->IOCIntforeignimportccallthreadsafe"wrapper"mkRead::CRead->IO(FunPtrCRead)typeCWrite=CString->CString->CSize->COff->PtrCFuseFileInfo->IOCIntforeignimportccallthreadsafe"wrapper"mkWrite::CWrite->IO(FunPtrCWrite)dataCStructStatFS-- struct fuse_stat_fstypeCStatFS=CString->PtrCStructStatFS->IOCIntforeignimportccallthreadsafe"wrapper"mkStatFS::CStatFS->IO(FunPtrCStatFS)typeCFlush=CString->PtrCFuseFileInfo->IOCIntforeignimportccallthreadsafe"wrapper"mkFlush::CFlush->IO(FunPtrCFlush)typeCRelease=CString->PtrCFuseFileInfo->IOCIntforeignimportccallthreadsafe"wrapper"mkRelease::CRelease->IO(FunPtrCRelease)typeCFSync=CString->Int->PtrCFuseFileInfo->IOCIntforeignimportccallthreadsafe"wrapper"mkFSync::CFSync->IO(FunPtrCFSync)-- XXX add *xattr bindingstypeCOpenDir=CString->PtrCFuseFileInfo->IOCIntforeignimportccallthreadsafe"wrapper"mkOpenDir::COpenDir->IO(FunPtrCOpenDir)typeCReadDir=CString->PtrCFillDirBuf->PtrCFillDir->COff->PtrCFuseFileInfo->IOCIntforeignimportccallthreadsafe"wrapper"mkReadDir::CReadDir->IO(FunPtrCReadDir)typeCReleaseDir=CString->PtrCFuseFileInfo->IOCIntforeignimportccallthreadsafe"wrapper"mkReleaseDir::CReleaseDir->IO(FunPtrCReleaseDir)typeCFSyncDir=CString->Int->PtrCFuseFileInfo->IOCIntforeignimportccallthreadsafe"wrapper"mkFSyncDir::CFSyncDir->IO(FunPtrCFSyncDir)-- CInt because anything would be fine as we don't use themtypeCInit=IO(PtrCInt)foreignimportccallthreadsafe"wrapper"mkInit::CInit->IO(FunPtrCInit)typeCDestroy=PtrCInt->IO()foreignimportccallthreadsafe"wrapper"mkDestroy::CDestroy->IO(FunPtrCDestroy)----- dynamic C called from Haskell---dataCDirHandle-- fuse_dirh_ttypeCDirFil=PtrCDirHandle->CString->Int->IOCInt-- fuse_dirfil_tforeignimportccallthreadsafe"dynamic"mkDirFil::FunPtrCDirFil->CDirFildataCFillDirBuf-- voidtypeCFillDir=PtrCFillDirBuf->CString->PtrCStat->COff->IOCIntforeignimportccallthreadsafe"dynamic"mkFillDir::FunPtrCFillDir->CFillDir