packages feed

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 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