HFuse 0.2.4.2 → 0.2.4.3
raw patch · 6 files changed
+257/−25 lines, 6 filesdep +HFusenew-component:exe:HelloFSPVP ok
version bump matches the API change (PVP)
Dependencies added: HFuse
API changes (from Hackage documentation)
Files
- CHANGELOG.md +14/−0
- HFuse.cabal +25/−8
- README +0/−16
- README.md +104/−0
- System/Fuse.hsc +1/−1
- examples/HelloFS.hs +113/−0
+ CHANGELOG.md view
@@ -0,0 +1,14 @@+Changelog+=========++v0.2.4.3+--------++- Added documentation+- Added HelloFS example++v0.2.4.2+--------++- Updated dependencies to run on latest base+- Updated cabal for FreeBSD support
HFuse.cabal view
@@ -1,37 +1,54 @@ Name: HFuse-Version: 0.2.4.2+Version: 0.2.4.3 License: BSD3 License-File: LICENSE Author: Jeremy Bobbio Maintainer: Montez Fitzpatrick <montezf@gmail.com> Synopsis: HFuse is a binding for the Linux FUSE library.-Description: Bindings for the FUSE library, compatible with OSXFUSE and FreeBSD.+Description: Bindings for the FUSE library, compatible with Linux, OSXFUSE and FreeBSD. Homepage: https://github.com/m15k/hfuse Category: System Stability: Experimental-Cabal-Version: >= 1.6+Cabal-Version: >= 1.10 Build-Type: Simple-Extra-source-files: README+Extra-source-files: + CHANGELOG.md+ README.md +flag developer+ default: False+ Library Build-Depends: base >= 4 && < 5, unix, bytestring- exposed-Modules: System.Fuse- Extensions: ForeignFunctionInterface ScopedTypeVariables EmptyDataDecls+ Exposed-Modules: System.Fuse+ Default-Extensions: ForeignFunctionInterface ScopedTypeVariables EmptyDataDecls Includes: dirent.h, fuse.h, fcntl.h Include-Dirs: /usr/include, /usr/local/include, . if os(darwin) CC-Options: "-DMACFUSE" Include-Dirs: /usr/local/include/osxfuse else- if os(freebsd) + if os(freebsd) Includes: sys/param.h, sys/mount.h CC-Options: "-Df_namelen=f_namemax" else Includes: sys/statfs.h- + Extra-Libraries: fuse Extra-Lib-Dirs: /usr/local/lib CC-Options: "-D_FILE_OFFSET_BITS=64"+ Default-Language: Haskell2010++executable HelloFS+ if flag(developer)+ buildable: True+ build-depends: base >= 4 && < 5, HFuse, unix, bytestring+ else+ buildable: False+ main-is: HelloFS.hs+ hs-source-dirs: examples+ ghc-options: -threaded+ Default-Language: Haskell2010 source-repository head type: git
− README
@@ -1,16 +0,0 @@-# Haskell FUSE API --Filesystem in Userspace ("FUSE") makes it possible to implement a filesystem as a userspace program.--This library is the Haskell binding to this library.--## Information--- Programs using HFuse should be compiled with -threaded.-- This now works for base 4.6+-- Added build options support for FreeBSD (contribution by https://github.com/pesco)--Added support for MacFUSE. Tested HelloFS and BindFS with:-* OSX 10.4.11 on a PPC G4 mac-* GHC 6.8.3-* MacFUSE 10.4-1.7.0
+ README.md view
@@ -0,0 +1,104 @@+# Haskell FUSE API++Filesystem in Userspace ("FUSE") makes it possible to implement a filesystem as a userspace program.++This library is the Haskell binding to this library.++## License++[BSD 3-Clause](./LICENSE)++## Information++- Programs using HFuse should be compiled with -threaded.+- This now works for base 4.6++- Added build options support for FreeBSD (contribution by https://github.com/pesco)+- MacFUSE should also work (https://github.com/mwotton/hfuse)++## Installation++All of the usual methods for installation will be supported.++**Installation via Hackage**++```+cabal install hfuse+```++**Installation for development**++Can either be handled via [Hackage](http://hackage.haskell.org/packages/search?terms=hfuse)++```+cabal unpack hfuse+cd HFuse-0.2.4.3+cabal sandbox init+cabal install --only-dependencies+cabal install -fdeveloper+```++Or the library can be installed via Github [repo][2]++```+git clone git://github.com/m15k/hfuse+cd hfuse+cabal sandbox init+cabal install --only-dependencies+cabal install -fdeveloper+```++**NOTE!**++* To use the sandboxes feature in Cabal your version must be higher than 1.18. *highly recommended*++## Development++To get a feel for HFuse, there are a number of example applications. They can be built by supplying the `-fdeveloper` [configuration flag][3] to Cabal.++> git clone https://github.com/m15k/hfuse++## Examples++[HelloFS](./examples/HelloFS.hs) is as basic as you get. Haskell version of the canonical [example](http://fuse.sourceforge.net/helloworld.html) from the FUSE project. Once compiled here is how you run HelloFS.++```+$ mkdir ~/fuseTest+$ ./HelloFS ~/fuseTest+```++This creates a file in the *fuseTest* directory. Now to test the application.++```+$ cat ~/fuseTest/hello+Hello World, HFuse!+```++To unmount issue the following command:++```+$ fusermount -u ~/fuseTest+```++## Other Samples++There are other projects on hackage which use HFuse as a dependency. Check [these](http://packdeps.haskellers.com/reverse/HFuse) out for a possibly richer experience than what is included with the [examples](./examples) folder.++If you lack for inspiration the FUSE [Wiki](http://sourceforge.net/p/fuse/wiki/FileSystems/) have amassed quite the list of links to downstream projects.++## Contributions++Help is always welcome. Pull requests are appreciated.++If you run into any problems or bugs, please report the issue on [Github][1]++## RoadMap++I would like to create the following examples:++- MemoryFS.hs := In-memory file system+- VBoxFS.hs := Mount VirtualBox disks as filesystem+- SSHFS.hs := SSH file system++[1]: https://github.com/m15k/google-drive-api/issues "Google-Drive-API Library Issues"+[2]: https://github.com/m15k/google-drive-api "Google-Drive-API Library"+[3]: http://www.haskell.org/cabal/users-guide/developing-packages.html#configurations "Cabal Configurations"
System/Fuse.hsc view
@@ -6,7 +6,7 @@ -- -- Maintainer : Montez Fitzpatrick -- Stability : experimental--- Portability : GHC 6.4-7.8.1+-- Portability : GHC 6.4-7.8.2 -- -- A binding for the FUSE (Filesystem in USErspace) library -- (<http://fuse.sourceforge.net/>), which allows filesystems to be implemented
+ examples/HelloFS.hs view
@@ -0,0 +1,113 @@+module Main where++import qualified Data.ByteString.Char8 as B+import Foreign.C.Error+import System.Posix.Types+import System.Posix.Files+import System.Posix.IO++import System.Fuse++type HT = ()++main :: IO ()+main = fuseMain helloFSOps defaultExceptionHandler++helloFSOps :: FuseOperations HT+helloFSOps = defaultFuseOps { fuseGetFileStat = helloGetFileStat+ , fuseOpen = helloOpen+ , fuseRead = helloRead + , fuseOpenDirectory = helloOpenDirectory+ , fuseReadDirectory = helloReadDirectory+ , fuseGetFileSystemStats = helloGetFileSystemStats+ }+helloString :: B.ByteString+helloString = B.pack "Hello World, HFuse!\n"++helloPath :: FilePath+helloPath = "/hello"+dirStat ctx = FileStat { statEntryType = Directory+ , statFileMode = foldr1 unionFileModes+ [ ownerReadMode+ , ownerExecuteMode+ , groupReadMode+ , groupExecuteMode+ , otherReadMode+ , otherExecuteMode+ ]+ , statLinkCount = 2+ , statFileOwner = fuseCtxUserID ctx+ , statFileGroup = fuseCtxGroupID ctx+ , statSpecialDeviceID = 0+ , statFileSize = 4096+ , statBlocks = 1+ , statAccessTime = 0+ , statModificationTime = 0+ , statStatusChangeTime = 0+ }++fileStat ctx = FileStat { statEntryType = RegularFile+ , statFileMode = foldr1 unionFileModes+ [ ownerReadMode+ , groupReadMode+ , otherReadMode+ ]+ , statLinkCount = 1+ , statFileOwner = fuseCtxUserID ctx+ , statFileGroup = fuseCtxGroupID ctx+ , statSpecialDeviceID = 0+ , statFileSize = fromIntegral $ B.length helloString+ , statBlocks = 1+ , statAccessTime = 0+ , statModificationTime = 0+ , statStatusChangeTime = 0+ }++helloGetFileStat :: FilePath -> IO (Either Errno FileStat)+helloGetFileStat "/" = do+ ctx <- getFuseContext+ return $ Right $ dirStat ctx+helloGetFileStat path | path == helloPath = do+ ctx <- getFuseContext+ return $ Right $ fileStat ctx+helloGetFileStat _ =+ return $ Left eNOENT++helloOpenDirectory "/" = return eOK+helloOpenDirectory _ = return eNOENT++helloReadDirectory :: FilePath -> IO (Either Errno [(FilePath, FileStat)])+helloReadDirectory "/" = do+ ctx <- getFuseContext+ return $ Right [(".", dirStat ctx)+ ,("..", dirStat ctx)+ ,(helloName, fileStat ctx)+ ]+ where (_:helloName) = helloPath+helloReadDirectory _ = return (Left (eNOENT))++helloOpen :: FilePath -> OpenMode -> OpenFileFlags -> IO (Either Errno HT)+helloOpen path mode flags+ | path == helloPath = case mode of+ ReadOnly -> return (Right ())+ _ -> return (Left eACCES)+ | otherwise = return (Left eNOENT)+++helloRead :: FilePath -> HT -> ByteCount -> FileOffset -> IO (Either Errno B.ByteString)+helloRead path _ byteCount offset+ | path == helloPath =+ return $ Right $ B.take (fromIntegral byteCount) $ B.drop (fromIntegral offset) helloString+ | otherwise = return $ Left eNOENT++helloGetFileSystemStats :: String -> IO (Either Errno FileSystemStats)+helloGetFileSystemStats str =+ return $ Right $ FileSystemStats+ { fsStatBlockSize = 512+ , fsStatBlockCount = 1+ , fsStatBlocksFree = 1+ , fsStatBlocksAvailable = 1+ , fsStatFileCount = 5+ , fsStatFilesFree = 10+ , fsStatMaxNameLength = 255+ }