diff --git a/HFuse.cabal b/HFuse.cabal
--- a/HFuse.cabal
+++ b/HFuse.cabal
@@ -1,5 +1,5 @@
 Name:                   HFuse
-Version:                0.2.1
+Version:                0.2.2
 License:                BSD3
 License-File:		LICENSE
 Author:                 Jeremy Bobbio
@@ -10,18 +10,16 @@
 Stability:              Experimental
 Cabal-Version:          >= 1.2
 Build-Type:             Simple
+Extra-source-files:     README
 
 Library
-  Build-Depends:          base, unix, bytestring
+  Build-Depends:          base >= 4 && < 5, unix, bytestring
   exposed-Modules:        System.Fuse
-  Extensions:             ForeignFunctionInterface PatternSignatures EmptyDataDecls
+  Extensions:             ForeignFunctionInterface ScopedTypeVariables EmptyDataDecls
   Includes:               sys/statfs.h, dirent.h, fuse.h, fcntl.h
   Include-Dirs:           /usr/include, /usr/local/include, .
   Extra-Libraries:        fuse
   Extra-Lib-Dirs:         /usr/local/lib
-  Includes:               fuse_wrappers.h
-  Install-Includes:       fuse_wrappers.h
-  C-Sources:              fuse_wrappers.c
   CC-Options:             -D_FILE_OFFSET_BITS=64
   if os(darwin) {
     CC-Options:           "-DMACFUSE"
diff --git a/README b/README
new file mode 100644
--- /dev/null
+++ b/README
@@ -0,0 +1,15 @@
+Programs using HFuse should be compiled with -threaded.
+
+HelloFS seems to work with:
+* Linux 2.6.24
+* The Glorious Glasgow Haskell Compilation System, version 6.8.2
+* fuse-2.6
+
+BindFS (?) is known to have a lurking deadlock problem.
+
+LiveFS is broken (from the old distribution).
+
+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
diff --git a/System/Fuse.hsc b/System/Fuse.hsc
--- a/System/Fuse.hsc
+++ b/System/Fuse.hsc
@@ -1,12 +1,12 @@
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  System.Fuse
--- Copyright   :  (c) Jérémy Bobbio
+-- Copyright   :  (c) Jérémy Bobbio, Taru Karttunen
 -- License     :  BSD-style
 -- 
--- Maintainer  :  jeremy.bobbio@etu.upmc.fr
+-- Maintainer  :  taruti@taruti.net, jeremy.bobbio@etu.upmc.fr
 -- Stability   :  experimental
--- Portability :  GHC 6.4
+-- Portability :  GHC 6.4-6.12
 --
 -- A binding for the FUSE (Filesystem in USErspace) library
 -- (<http://fuse.sourceforge.net/>), which allows filesystems to be implemented
@@ -28,7 +28,7 @@
       module Foreign.C.Error
     , FuseOperations(..)
     , defaultFuseOps
-    , fuseMain -- :: FuseOperations -> (Exception -> IO Errno) -> IO ()
+    , fuseMain -- :: FuseOperations fh -> (Exception -> IO Errno) -> IO ()
     , defaultExceptionHandler -- :: Exception -> IO Errno
       -- * Operations datatypes
     , FileStat(..)
@@ -48,7 +48,8 @@
 
 import Prelude hiding ( Read )
 
-import Control.Exception as E( Exception, handle, finally )
+import Control.Monad
+import Control.Exception as E(Exception, handle, finally, SomeException)
 import qualified Data.ByteString.Char8    as B
 import qualified Data.ByteString.Internal as B
 import qualified Data.ByteString.Unsafe   as B
@@ -57,10 +58,16 @@
 import Foreign.C.Error
 import Foreign.Marshal
 import System.Environment ( getProgName, getArgs )
-import System.IO ( hPutStrLn, stderr )
+import System.IO ( hPutStrLn, stderr, withFile, stdin, stdout, IOMode(..) )
 import System.Posix.Types
 import System.Posix.Files ( accessModes, intersectFileModes, unionFileModes )
+import System.Posix.Directory(changeWorkingDirectory)
+import System.Posix.Process(forkProcess,createSession,exitImmediately)
 import System.Posix.IO ( OpenMode(..), OpenFileFlags(..) )
+import qualified System.Posix.Signals as Signals
+import GHC.IO.Handle(hDuplicateTo)
+import System.Exit
+import qualified System.IO.Error as IO(catch,ioeGetErrorString)
 
 -- TODO: FileMode -> Permissions
 -- TODO: Arguments !
@@ -79,8 +86,6 @@
 #include <fuse.h>
 #include <fcntl.h>
 
-#include "fuse_wrappers.h"
-
 {- $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.
@@ -426,33 +431,26 @@
                    , fuseDestroy = return ()
                    }
 
+-- Allocates a fuse_args struct to hold the commandline arguments.
+withFuseArgs :: (Ptr CFuseArgs -> IO b) -> IO b
+withFuseArgs f =
+    do prog <- getProgName
+       args <- getArgs
+       let allArgs = (prog:args)
+           argc = length allArgs
+       withMany withCString allArgs (\ cArgs ->
+           withArray cArgs $ (\ pArgv ->
+               allocaBytes (#size struct fuse_args) (\ fuseArgs ->
+                    do (#poke struct fuse_args, argc) fuseArgs argc
+                       (#poke struct fuse_args, argv) fuseArgs pArgv
+                       (#poke struct fuse_args, allocated) fuseArgs (0::CInt)
+                       finally (f fuseArgs)
+                               (fuse_opt_free_args fuseArgs))))
 
--- | 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 fh -> (Exception -> IO Errno) -> IO ()
-fuseMain ops handler =
+withStructFuse :: forall e fh b. Exception e => Ptr CFuseChan -> Ptr CFuseArgs -> FuseOperations fh -> (e -> IO Errno) -> (Ptr CStructFuse -> IO b) -> IO b
+withStructFuse pFuseChan pArgs ops handler f =
     allocaBytes (#size struct fuse_operations) $ \ pOps -> do
+      bzero pOps (#size struct fuse_operations)
       mkGetAttr    wrapGetAttr    >>= (#poke struct fuse_operations, getattr)    pOps
       mkReadLink   wrapReadLink   >>= (#poke struct fuse_operations, readlink)   pOps 
       -- getdir is deprecated and thus unsupported
@@ -485,17 +483,17 @@
       mkReadDir    wrapReadDir    >>= (#poke struct fuse_operations, readdir)    pOps
       mkReleaseDir wrapReleaseDir >>= (#poke struct fuse_operations, releasedir) pOps
       mkFSyncDir   wrapFSyncDir   >>= (#poke struct fuse_operations, fsyncdir)   pOps
+#if FUSE_MINOR_VERSION > 4
       mkAccess     wrapAccess     >>= (#poke struct fuse_operations, access)     pOps
+#endif
       mkInit       wrapInit       >>= (#poke struct fuse_operations, init)       pOps
       mkDestroy    wrapDestroy    >>= (#poke struct fuse_operations, destroy)    pOps
-      prog <- getProgName
-      args <- getArgs
-      let allArgs = (prog:args)
-          argc    = length allArgs
-      withMany withCString allArgs $ \ pAddrs  ->
-          withArray pAddrs $ \ pArgv ->
-              do fuse_main_wrapper argc pArgv pOps
-    where fuseHandler :: Exception -> IO CInt
+      structFuse <- fuse_new pFuseChan pArgs pOps (#size struct fuse_operations) nullPtr 
+      if structFuse == nullPtr
+        then fail ""
+        else E.finally (f structFuse)
+                       (fuse_destroy structFuse)
+    where fuseHandler :: e -> IO CInt
           fuseHandler e = handler e >>= return . unErrno
           wrapGetAttr :: CGetAttr
           wrapGetAttr pFilePath pStat = handle fuseHandler $
@@ -715,19 +713,138 @@
                  return (- errno)
           wrapInit :: CInit
           wrapInit pFuseConnInfo =
-            handle (\e -> hPutStrLn stderr (show e) >> return nullPtr) $
+            handle (\e -> defaultExceptionHandler e >> return nullPtr) $
               do fuseInit ops
                  return nullPtr
           wrapDestroy :: CDestroy
-          wrapDestroy _ = handle (\e -> hPutStrLn stderr (show e)) $
+          wrapDestroy _ = handle (\e -> defaultExceptionHandler e >> return ()) $
               do fuseDestroy ops
 
 -- | Default exception handler.
 -- Print the exception on error output and returns 'eFAULT'.
-defaultExceptionHandler :: (Exception -> IO Errno)
+defaultExceptionHandler :: (SomeException -> IO Errno)
 defaultExceptionHandler e = hPutStrLn stderr (show e) >> return eFAULT
 
+-- Calls fuse_parse_cmdline to parses the part of the commandline arguments that
+-- we care about. fuse_parse_cmdline will modify the CFuseArgs struct passed in
+-- to remove those arguments; the CFuseArgs struct containing remaining arguments
+-- must be passed to fuse_mount/fuse_new.
+--
+-- The multithreaded runtime will be used regardless of the threading flag!
+-- See the comment in fuse_session_exit for why.
+fuseParseCommandLine :: Ptr CFuseArgs -> IO (Maybe (Maybe String, Bool, Bool))
+fuseParseCommandLine pArgs = 
+    alloca (\pMountPt -> 
+        alloca (\pMultiThreaded ->
+            alloca (\pFG ->
+                do poke pMultiThreaded 0
+                   poke pFG 0
+                   retval <- fuse_parse_cmdline pArgs pMountPt pMultiThreaded pFG
+                   if retval == 0
+                     then do cMountPt <- peek pMountPt
+                             mountPt <- if cMountPt /= nullPtr
+                                          then do a <- peekCString cMountPt
+                                                  free cMountPt
+                                                  return $ Just a
+                                          else return $ Nothing
+                             multiThreaded <- peek pMultiThreaded
+                             foreground <- peek pFG
+                             return $ Just (mountPt, multiThreaded == 1, foreground == 1)
+                     else return Nothing)))
 
+-- haskell version of daemon(2)
+-- Mimic's daemon()s use of _exit() instead of exit(); we depend on this in fuseMainReal,
+-- because otherwise we'll unmount the filesystem when the foreground process exits.
+daemon f = forkProcess d >> exitImmediately ExitSuccess
+  where d = IO.catch (do createSession
+                         changeWorkingDirectory "/"
+                         -- need to open /dev/null twice because hDuplicateTo can't dup a ReadWriteMode to a ReadMode handle
+                         withFile "/dev/null" WriteMode (\devNullOut ->
+                           do hDuplicateTo devNullOut stdout
+                              hDuplicateTo devNullOut stderr)
+                         withFile "/dev/null" ReadMode (\devNullIn -> hDuplicateTo devNullIn stdin)
+                         f
+                         exitWith ExitSuccess)
+                     (const exitFailure)
+
+-- Installs signal handlers for the duration of the main loop.
+withSignalHandlers exitHandler f =
+    do let sigHandler = Signals.CatchOnce exitHandler
+       Signals.installHandler Signals.keyboardSignal sigHandler Nothing
+       Signals.installHandler Signals.lostConnection sigHandler Nothing
+       Signals.installHandler Signals.softwareTermination sigHandler Nothing
+       Signals.installHandler Signals.openEndedPipe Signals.Ignore Nothing
+       E.finally f
+                 (do Signals.installHandler Signals.keyboardSignal Signals.Default Nothing
+                     Signals.installHandler Signals.lostConnection Signals.Default Nothing
+                     Signals.installHandler Signals.softwareTermination Signals.Default Nothing
+                     Signals.installHandler Signals.openEndedPipe Signals.Default Nothing)
+
+-- Mounts the filesystem, forks, and then starts fuse
+fuseMainReal foreground ops handler pArgs mountPt =
+    withCString mountPt (\cMountPt ->
+      do pFuseChan <- fuse_mount cMountPt pArgs
+         if pFuseChan == nullPtr
+           then exitFailure -- fuse will print an error message why this happened
+           else (withStructFuse pFuseChan pArgs ops handler (\pFuse ->
+                  E.finally 
+                     (if foreground -- finally ready to fork
+                       then changeWorkingDirectory "/" >> (procMain pFuse)
+                       else daemon (procMain pFuse))
+                     (fuse_unmount cMountPt pFuseChan))))
+
+    -- here, we're finally inside the daemon process, we can run the main loop
+    where procMain pFuse = do session <- fuse_get_session pFuse
+                              -- calling fuse_session_exit to exit the main loop only
+                              -- appears to work with the multithreaded fuse loop.
+                              -- In the single-threaded case, FUSE depends on their
+                              -- recv() call to finish with EINTR when signals arrive.
+                              -- This doesn't happen with GHC's signal handling in place.
+                              withSignalHandlers (fuse_session_exit session) $
+                                 do retVal <- fuse_loop_mt pFuse
+                                    if retVal == 1 
+                                      then exitWith ExitSuccess
+                                      else exitFailure
+                                    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 :: Exception e => FuseOperations fh -> (e -> IO Errno) -> IO ()
+fuseMain ops handler =
+    -- this used to be implemented using libfuse's fuse_main. Doing this will fork()
+    -- from C behind the GHC runtime's back, which deadlocks in GHC 6.8.
+    -- Instead, we reimplement fuse_main in Haskell using the forkProcess and the
+    -- lower-level fuse_new/fuse_loop_mt API.
+    IO.catch
+       (withFuseArgs (\pArgs ->
+         do cmd <- fuseParseCommandLine pArgs
+            case cmd of
+              Nothing -> fail ""
+              Just (Nothing, _, _) -> fail "Usage error: mount point required"
+              Just (Just mountPt, _, foreground) -> fuseMainReal foreground ops handler pArgs mountPt))
+       ((\errStr -> when (not $ null errStr) (putStrLn errStr) >> exitFailure) . IO.ioeGetErrorString)
+
 -----------------------------------------------------------------------------
 -- Miscellaneous utilities
 
@@ -752,14 +869,49 @@
 -- exported C called from Haskell
 ---  
 
-data CFuseOperations
-foreign import ccall threadsafe "fuse_wrappers.h fuse_main_wrapper"
-    fuse_main_wrapper :: Int -> Ptr CString -> Ptr CFuseOperations -> IO ()
+data CFuseArgs -- struct fuse_args
 
-data StructFuse
-foreign import ccall threadsafe "fuse.h fuse_get_context"
-    fuse_get_context :: IO (Ptr StructFuse)
+data CFuseChan -- struct fuse_chan
+foreign import ccall safe "fuse.h fuse_mount"
+    fuse_mount :: CString -> Ptr CFuseArgs -> IO (Ptr CFuseChan)
 
+foreign import ccall safe "fuse.h fuse_unmount"
+    fuse_unmount :: CString -> Ptr CFuseChan -> IO ()
+
+data CFuseSession -- struct fuse_session
+foreign import ccall safe "fuse.h fuse_get_session"
+    fuse_get_session :: Ptr CStructFuse -> IO (Ptr CFuseSession)
+
+foreign import ccall safe "fuse.h fuse_session_exit"
+    fuse_session_exit :: Ptr CFuseSession -> IO ()
+
+foreign import ccall safe "fuse.h fuse_set_signal_handlers"
+    fuse_set_signal_handlers :: Ptr CFuseSession -> IO Int
+
+foreign import ccall safe "fuse.h fuse_remove_signal_handlers"
+    fuse_remove_signal_handlers :: Ptr CFuseSession -> IO ()
+
+foreign import ccall safe "fuse.h fuse_parse_cmdline"
+    fuse_parse_cmdline :: Ptr CFuseArgs -> Ptr CString -> Ptr Int -> Ptr Int -> IO Int
+
+data CStructFuse -- struct fuse
+data CFuseOperations -- struct fuse_operations
+foreign import ccall safe "fuse.h fuse_new"
+    fuse_new :: Ptr CFuseChan -> Ptr CFuseArgs -> Ptr CFuseOperations -> Int -> Ptr () -> IO (Ptr CStructFuse)
+
+foreign import ccall safe "fuse.h fuse_destroy"
+    fuse_destroy :: Ptr CStructFuse -> IO ()
+
+foreign import ccall safe "fuse.h fuse_opt_free_args"
+    fuse_opt_free_args :: Ptr CFuseArgs -> IO ()
+
+foreign import ccall safe "fuse.h fuse_loop_mt"
+    fuse_loop_mt :: Ptr CStructFuse -> IO Int
+
+data CFuseContext
+foreign import ccall safe "fuse.h fuse_get_context"
+    fuse_get_context :: IO (Ptr CFuseContext)
+
 ---
 -- dynamic Haskell called from C
 ---
@@ -769,117 +921,117 @@
 
 data CStat -- struct stat
 type CGetAttr = CString -> Ptr CStat -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkGetAttr :: CGetAttr -> IO (FunPtr CGetAttr)
 
 type CReadLink = CString -> CString -> CSize -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkReadLink :: CReadLink -> IO (FunPtr CReadLink)
 
 type CMkNod = CString -> CMode -> CDev -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkMkNod :: CMkNod -> IO (FunPtr CMkNod)
 
 type CMkDir = CString -> CMode -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkMkDir :: CMkDir -> IO (FunPtr CMkDir)
 
 type CUnlink = CString -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkUnlink :: CUnlink -> IO (FunPtr CUnlink)
 
 type CRmDir = CString -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkRmDir :: CRmDir -> IO (FunPtr CRmDir)
 
 type CSymLink = CString -> CString -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkSymLink :: CSymLink -> IO (FunPtr CSymLink)
 
 type CRename = CString -> CString -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkRename :: CRename -> IO (FunPtr CRename)
 
 type CLink = CString -> CString -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkLink :: CLink -> IO (FunPtr CLink)
 
 type CChMod = CString -> CMode -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkChMod :: CChMod -> IO (FunPtr CChMod)
 
 type CChOwn = CString -> CUid -> CGid -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkChOwn :: CChOwn -> IO (FunPtr CChOwn)
 
 type CTruncate = CString -> COff -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkTruncate :: CTruncate -> IO (FunPtr CTruncate)
 
 data CUTimBuf -- struct utimbuf
 type CUTime = CString -> Ptr CUTimBuf -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkUTime :: CUTime -> IO (FunPtr CUTime)
 
 type COpen = CString -> Ptr CFuseFileInfo -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkOpen :: COpen -> IO (FunPtr COpen)
 
 type CRead = CString -> CString -> CSize -> COff -> Ptr CFuseFileInfo -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkRead :: CRead -> IO (FunPtr CRead)
 
 type CWrite = CString -> CString -> CSize -> COff -> Ptr CFuseFileInfo -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkWrite :: CWrite -> IO (FunPtr CWrite)
 
 data CStructStatFS -- struct fuse_stat_fs
 type CStatFS = CString -> Ptr CStructStatFS -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkStatFS :: CStatFS -> IO (FunPtr CStatFS)
 
 type CFlush = CString -> Ptr CFuseFileInfo -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkFlush :: CFlush -> IO (FunPtr CFlush)
 
 type CRelease = CString -> Ptr CFuseFileInfo -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkRelease :: CRelease -> IO (FunPtr CRelease)
 
 type CFSync = CString -> Int -> Ptr CFuseFileInfo -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkFSync :: CFSync -> IO (FunPtr CFSync) 
 
 -- XXX add *xattr bindings
 
 type COpenDir = CString -> Ptr CFuseFileInfo -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkOpenDir :: COpenDir -> IO (FunPtr COpenDir)
 
 type CReadDir = CString -> Ptr CFillDirBuf -> FunPtr CFillDir -> COff
              -> Ptr CFuseFileInfo -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkReadDir :: CReadDir -> IO (FunPtr CReadDir)
 
 type CReleaseDir = CString -> Ptr CFuseFileInfo -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkReleaseDir :: CReleaseDir -> IO (FunPtr CReleaseDir)
 
 type CFSyncDir = CString -> Int -> Ptr CFuseFileInfo -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkFSyncDir :: CFSyncDir -> IO (FunPtr CFSyncDir)
 
 type CAccess = CString -> CInt -> IO CInt
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkAccess :: CAccess -> IO (FunPtr CAccess)
 
 -- CInt because anything would be fine as we don't use them
 type CInit = Ptr CFuseConnInfo -> IO (Ptr CInt)
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkInit :: CInit -> IO (FunPtr CInit)
 
 type CDestroy = Ptr CInt -> IO ()
-foreign import ccall threadsafe "wrapper"
+foreign import ccall safe "wrapper"
     mkDestroy :: CDestroy -> IO (FunPtr CDestroy)
 
 ----
@@ -907,10 +1059,15 @@
 
 data CDirHandle -- fuse_dirh_t
 type CDirFil = Ptr CDirHandle -> CString -> Int -> IO CInt -- fuse_dirfil_t
-foreign import ccall threadsafe "dynamic"
+foreign import ccall safe "dynamic"
     mkDirFil :: FunPtr CDirFil -> CDirFil
 
 data CFillDirBuf -- void
 type CFillDir = Ptr CFillDirBuf -> CString -> Ptr CStat -> COff -> IO CInt
-foreign import ccall threadsafe "dynamic"
+
+foreign import ccall safe "dynamic"
     mkFillDir :: FunPtr CFillDir -> CFillDir
+
+foreign import ccall safe "bzero"
+    bzero :: Ptr a -> Int -> IO ()
+
diff --git a/fuse_wrappers.c b/fuse_wrappers.c
deleted file mode 100644
--- a/fuse_wrappers.c
+++ /dev/null
@@ -1,11 +0,0 @@
-#define FUSE_USE_VERSION 26
-
-#include "fuse_wrappers.h"
-
-int
-fuse_main_wrapper (int argc,
-                   char *argv[],
-                   const struct fuse_operations *op)
-{
-    return (fuse_main (argc, argv, op, NULL));
-}
diff --git a/fuse_wrappers.h b/fuse_wrappers.h
deleted file mode 100644
--- a/fuse_wrappers.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#include <fuse.h>
-
-int fuse_main_wrapper (int argc, char *argv[], const struct fuse_operations *op);
