libfuse3 0.1.1.0 → 0.1.1.1
raw patch · 7 files changed
+148/−31 lines, 7 filesdep +hspecdep +processdep +temporarydep ~basedep ~bytestringdep ~unixPVP ok
version bump matches the API change (PVP)
Dependencies added: hspec, process, temporary
Dependency ranges changed: base, bytestring, unix
API changes (from Hackage documentation)
Files
- CHANGELOG.md +6/−0
- README.md +3/−3
- configure +9/−9
- configure.ac +1/−1
- libfuse3.cabal +18/−1
- src/System/LibFuse3/Internal.hsc +1/−17
- test/integtest/Main.hs +110/−0
CHANGELOG.md view
@@ -1,5 +1,11 @@ # Revision history for libfuse3 +## 0.1.1.1 -- 2020-10-06++* Minor improvements on the documentations+* Add tests+* Correct the version numbers in `configure.ac`+ ## 0.1.1.0 -- 2020-08-29 * Improve the situation with signals
README.md view
@@ -12,7 +12,7 @@ This package depends on the C library [libfuse][libfuse] and `pkg-config`. Please install them with your system package manager before building this package. For example, on Ubuntu: ```sh-sudo apt-get update && sudo apt-get install libfuse3-dev pkg-config+sudo apt-get update && sudo apt-get install libfuse3-dev fuse3 pkg-config ``` **NOTE:** `libfuse3-dev` is not available until Ubuntu-20.04 (a.k.a. "focal").@@ -44,7 +44,7 @@ - A signal needs to be sent twice to stop the process and unmount the filesystem. - This means you have to run `kill -2 <pid>` twice or hit `Ctrl-C` twice (if running in foreground).- - On the other hand, `fusermount -u` can unmount the filesystem on the first attempt.+ - On the other hand, `fusermount3 -u` can unmount the filesystem on the first attempt. - Not all Haskell-friendly bindings to the FUSE operations are implemented yet, including but not limited to: - `struct fuse_conn_info`. The availability of filesystem capabilities such as `FUSE_CAP_HANDLE_KILLPRIV` can't be checked. - Setting the fields of `struct fuse_file_info` from the certain fuse operations.@@ -58,7 +58,7 @@ - [HFuse][HFuse]: The bindings to libfuse-2.x - `libfuse3` is based on `HFuse` (with massive rewrites). - `libfuse3` has more complete API and exposes internal (and unstable) API to allow workarounds.-- [fuse-rs][fuse-rs]: The Rust implementation of FUSE. Unlike this package, `fuse-rs` implements the FUSE protocol itself (i.e. replaces `libfuse`). See [its README](https://github.com/zargony/fuse-rs) for overview.+- [fuse-rs][fuse-rs]: The Rust implementation of FUSE. Unlike this package, `fuse-rs` implements the FUSE protocol itself, mostly reimplementing `libfuse` in Rust. See [its README](https://github.com/zargony/fuse-rs) for overview. [libfuse]: https://github.com/libfuse/libfuse [HFuse]: https://github.com/m15k/hfuse
configure view
@@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles.-# Generated by GNU Autoconf 2.69 for Haskell libfuse3 package 0.1.0.0.+# Generated by GNU Autoconf 2.69 for Haskell libfuse3 package 0.1.1.1. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.@@ -576,8 +576,8 @@ # Identity of this package. PACKAGE_NAME='Haskell libfuse3 package' PACKAGE_TARNAME='haskell-libfuse3-package'-PACKAGE_VERSION='0.1.0.0'-PACKAGE_STRING='Haskell libfuse3 package 0.1.0.0'+PACKAGE_VERSION='0.1.1.1'+PACKAGE_STRING='Haskell libfuse3 package 0.1.1.1' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1192,7 +1192,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF-\`configure' configures Haskell libfuse3 package 0.1.0.0 to adapt to many kinds of systems.+\`configure' configures Haskell libfuse3 package 0.1.1.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1254,7 +1254,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in- short | recursive ) echo "Configuration of Haskell libfuse3 package 0.1.0.0:";;+ short | recursive ) echo "Configuration of Haskell libfuse3 package 0.1.1.1:";; esac cat <<\_ACEOF @@ -1341,7 +1341,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF-Haskell libfuse3 package configure 0.1.0.0+Haskell libfuse3 package configure 0.1.1.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc.@@ -1453,7 +1453,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Haskell libfuse3 package $as_me 0.1.0.0, which was+It was created by Haskell libfuse3 package $as_me 0.1.1.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@@@ -3340,7 +3340,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log="-This file was extended by Haskell libfuse3 package $as_me 0.1.0.0, which was+This file was extended by Haskell libfuse3 package $as_me 0.1.1.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES@@ -3402,7 +3402,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\-Haskell libfuse3 package config.status 0.1.0.0+Haskell libfuse3 package config.status 0.1.1.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\"
configure.ac view
@@ -1,4 +1,4 @@-AC_INIT([Haskell libfuse3 package], [0.1.1.0])+AC_INIT([Haskell libfuse3 package], [0.1.1.1]) # Safety check: Ensure that we are in the correct source directory. AC_CONFIG_SRCDIR([libfuse3.cabal])
libfuse3.cabal view
@@ -3,7 +3,7 @@ -- For further documentation, see http://haskell.org/cabal/users-guide/ name: libfuse3-version: 0.1.1.0+version: 0.1.1.1 synopsis: A Haskell binding for libfuse-3.x description: Bindings for libfuse, the FUSE userspace reference implementation, of version 3.x. Compatible with Linux. -- bug-reports:@@ -52,6 +52,23 @@ include-dirs: include default-language: Haskell2010 ghc-options: -Wall -fdefer-typed-holes++test-suite integtest+ type: exitcode-stdio-1.0+ main-is: Main.hs+ build-depends: libfuse3, base+ , bytestring+ , directory+ , filepath+ , hspec+ , process+ , temporary+ , unix+ -- other-modules:+ -- other-extensions:+ hs-source-dirs: test/integtest+ default-language: Haskell2010+ ghc-options: -Wall -fdefer-typed-holes -threaded executable null if flag(examples)
src/System/LibFuse3/Internal.hsc view
@@ -928,7 +928,7 @@ -- is unmounted. -- Adding the RTS option @--install-signal-handlers=no@ does not fix the issue. --- -- On the other hand, @fusermount -u@ successfully unmounts the filesystem on the first+ -- On the other hand, @fusermount3 -u@ successfully unmounts the filesystem on the first -- attempt. withSignalHandlers (C.fuse_session_exit session) $ do retVal <- C.fuse_loop_mt_31 pFuse cloneFd@@ -954,22 +954,6 @@ -- 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------ * passes all options after @--@ to the fusermount program------ * mounts the filesystem by calling @fusermount@------ * installs signal handlers------ * registers an exit handler to unmount the filesystem on program exit------ * registers the operations------ * calls FUSE event loop fuseMain :: Exception e => FuseOperations fh dh -> (e -> IO Errno) -> IO () fuseMain ops handler = do -- this used to be implemented using libfuse's fuse_main. Doing this will fork()
+ test/integtest/Main.hs view
@@ -0,0 +1,110 @@+-- Please note that @cabal v2-test@ handles the test output very badly for some reason;+-- the output is duplicated and interleaved.+--+-- Use @cabal v2-run -- integtest@ for more reliable output.+module Main where++import Control.Exception (SomeException, finally)+import Control.Monad (when)+import Data.Bits ((.|.))+import Data.Maybe (isNothing)+import Foreign.C (eIO, eNOENT)+import System.Directory (findExecutable, listDirectory)+import System.Environment (withArgs)+import System.Exit (exitFailure)+import System.FilePath ((</>))+import System.IO (hPrint, hPutStrLn, stderr)+import System.IO.Temp (withSystemTempDirectory)+import System.LibFuse3+import System.Posix.Files (directoryMode, regularFileMode)+import System.Posix.Process (getProcessStatus, forkProcess)+import System.Process (callProcess)+import Test.Hspec (Spec, SpecWith, around, describe, hspec, it, shouldBe)++import qualified Data.ByteString as B++-- | Runs a spec on a FUSE filesystem mounted on a temporary directory.+withFileSystem :: FuseOperations fh dh -> SpecWith FilePath -> Spec+withFileSystem ops = around $ \theSpec ->+ withSystemTempDirectory "libfuse3test" $ \mountPoint -> do+ let unmount = do+ hPutStrLn stderr $ "unmounting : " <> mountPoint+ callProcess "fusermount3" ["-u", mountPoint]+ withArgs [mountPoint] $ do+ hPutStrLn stderr $ "mounting on: " <> mountPoint+ pid <- forkProcess $ fuseMain ops (\e -> hPrint stderr (e :: SomeException) >> pure eIO)+ flip finally unmount $ do+ -- wait for fuseMain to daemonize+ _ <- getProcessStatus True False pid+ theSpec mountPoint++specs :: Spec+specs = do+ -- A basic test of fuseGetattr; we get what we give+ describe "fuseGetattr" $+ let stat = defaultFileStat+ { fileMode = directoryMode .|. 0o755+ , linkCount = 1+ }+ ops = defaultFuseOperations+ { fuseGetattr = Just $ \path _ -> case path of+ "/" -> pure $ Right stat+ _ -> pure $ Left eNOENT+ }+ in withFileSystem ops $ it "getFileStat reads the stat as is" $ \mountPoint -> do+ -- assumes that `getFileStat` works correctly+ stat' <- getFileStat mountPoint+ -- ignore differences in fileID+ -- TODO test use_ino?+ stat' { fileID = fileID stat } `shouldBe` stat++ -- If `fuseOpen` is not defined, make sure that `fuseRead` doesn't throw unless+ -- the file handle is evaluated.+ describe "fuseRead without fuseOpen" $+ let content = B.singleton 0+ ops = defaultFuseOperations+ { fuseGetattr = Just $ \path mfh ->+ case mfh of+ Just _ -> pure $ Left eIO -- this should never happen+ Nothing+ | path == "/file" -> pure $ Right $ defaultFileStat+ { fileMode = regularFileMode .|. 0o644+ , fileSize = 1+ }+ | otherwise -> pure $ Left eNOENT+ , fuseRead = Just $ \path _fh len off ->+ -- check that evaluating the args other than the file handle is harmless+ path `seq` len `seq` off `seq` (pure $ Right content)+ }+ in withFileSystem ops $ it "fileRead reads without a crash" $ \mountPoint -> do+ readContent <- B.readFile $ mountPoint </> "file"+ readContent `shouldBe` content++ -- If `fuseOpendir` is not defined, make sure that `fuseReaddir` doesn't throw unless+ -- the directory handle is evaluated.+ describe "fuseReaddir without fuseOpendir" $+ let ops = defaultFuseOperations+ { fuseGetattr = Just $ \path _ ->+ case () of+ _ | path == "/dir/file" -> pure $ Right $ defaultFileStat+ { fileMode = regularFileMode .|. 0o644+ , fileSize = 1+ }+ | path == "/dir" -> pure $ Right $ defaultFileStat+ { fileMode = directoryMode .|. 0o755+ }+ | otherwise -> pure $ Left eNOENT+ , fuseReaddir = Just $ \path _dh ->+ path `seq` (pure $ Right $ [(".", Nothing), ("..", Nothing), ("file", Nothing)])+ }+ in withFileSystem ops $ it "fileReaddir reads without a crash" $ \mountPoint -> do+ entries <- listDirectory $ mountPoint </> "dir"+ entries `shouldBe` ["file"]++main :: IO ()+main = do+ mfusermount3 <- findExecutable "fusermount3"+ when (isNothing mfusermount3) $ do+ hPutStrLn stderr "Command 'fusermount3' not found. Please install it first. It usually comes with a package named like 'fuse3'."+ exitFailure+ hspec specs