-
Notifications
You must be signed in to change notification settings - Fork 21
/
HelloFS.hs
113 lines (99 loc) · 4.26 KB
/
HelloFS.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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
}