{- |This module provides an interface to the system mount and umount functions. -} module System.Linux.Mount ( -- * Bindings to system functions mount , umount , umountWith , forceUmount -- *MountFlag , MountFlag (..) -- *DriverData , DriverData (..) , noData -- *UmountFlag , UmountFlag (..) ) where #include import Data.Bits import Data.ByteString hiding (foldl, map) import Foreign import Foreign.C import Foreign.Marshal.Alloc -- | Mounts a filesystem. mount :: String -- ^ device file -> FilePath -- ^ mount point -> String -- ^ filesystem type -> [MountFlag] -- ^ list of mount options -> DriverData -- ^ driver specific options -> IO () mount dev dir typ xs (DriverData ptr) = throwErrnoIfMinus1_ "mount" $ do cdev <- newCString dev cdir <- newCString dir ctype <- newCString typ ret <- useAsCString ptr (\x-> c_mount cdev cdir ctype (combineBitMasks xs) (castPtr x) ) free cdev free cdir free ctype return ret foreign import ccall unsafe "mount" c_mount :: Ptr CChar -> Ptr CChar -> Ptr CChar -> CULong -> Ptr a -> IO CInt -- | Umounts a filesystem. umount :: String -- ^ mount point -> IO () umount str = throwErrnoIfMinus1_ "umount" (withCString str (\cstr -> (c_umount cstr))) foreign import ccall unsafe "umount" c_umount :: Ptr CChar -> IO CInt -- | Umounts a filesystem using specific umount options. umountWith :: UmountFlag -- ^ umount options -> String -- ^ mount point -> IO () umountWith flag str = genUmount2 flag str "umountWith" -- |Forces the filesystem umount (@forceUmount str = 'umountWith' 'Force' str@). forceUmount :: String -- ^ mount point -> IO () forceUmount str = genUmount2 Force str "forceUmount" genUmount2 flag str errmsg = throwErrnoIfMinus1_ errmsg (withCString str (\cstr -> c_umount2 cstr (fromIntegral $ fromEnum flag) ) ) foreign import ccall unsafe "umount2" c_umount2 :: Ptr CChar -> CInt -> IO CInt -- |MountFlag specifies a filesystem independent option to be used -- when mounting a filesystem data MountFlag = Rdonly | Nosuid | Nodev | Noexec | Synchronous | Remount | Mandlock | Dirsync | Noatime | Nodiratime | Bind | Move | Rec | Silent | Posixacl | Unbindable | Private | Slave | Shared | Relatime | Kernmount | IVersion | Strictatime | Active | Nouser deriving (Eq, Read, Show) instance Enum MountFlag where fromEnum Rdonly = fromIntegral msRdonly fromEnum Nosuid = fromIntegral msNosuid fromEnum Nodev = fromIntegral msNodev fromEnum Noexec = fromIntegral msNoexec fromEnum Synchronous = fromIntegral msSynchronous fromEnum Remount = fromIntegral msRemount fromEnum Mandlock = fromIntegral msMandlock fromEnum Dirsync = fromIntegral msDirsync fromEnum Noatime = fromIntegral msNoatime fromEnum Nodiratime = fromIntegral msNodiratime fromEnum Bind = fromIntegral msBind fromEnum Move = fromIntegral msMove fromEnum Rec = fromIntegral msRec fromEnum Silent = fromIntegral msSilent fromEnum Posixacl = fromIntegral msPosixacl fromEnum Unbindable = fromIntegral msUnbindable fromEnum Private = fromIntegral msPrivate fromEnum Slave = fromIntegral msSlave fromEnum Shared = fromIntegral msShared fromEnum Relatime = fromIntegral msRelatime fromEnum Kernmount = fromIntegral msKernmount fromEnum IVersion = fromIntegral msIVersion fromEnum Strictatime = fromIntegral msStrictatime fromEnum Active = fromIntegral msActive fromEnum Nouser = fromIntegral msNouser toEnum n | n == fromIntegral msRdonly = Rdonly | n == fromIntegral msNosuid = Nosuid | n == fromIntegral msNodev = Nodev | n == fromIntegral msNoexec = Noexec | n == fromIntegral msSynchronous = Synchronous | n == fromIntegral msRemount = Remount | n == fromIntegral msMandlock = Mandlock | n == fromIntegral msDirsync = Dirsync | n == fromIntegral msNoatime = Noatime | n == fromIntegral msNodiratime = Nodiratime | n == fromIntegral msBind = Bind | n == fromIntegral msMove = Move | n == fromIntegral msRec = Rec | n == fromIntegral msSilent = Silent | n == fromIntegral msPosixacl = Posixacl | n == fromIntegral msUnbindable = Unbindable | n == fromIntegral msPrivate = Private | n == fromIntegral msSlave = Slave | n == fromIntegral msShared = Shared | n == fromIntegral msRelatime = Relatime | n == fromIntegral msKernmount = Kernmount | n == fromIntegral msIVersion = IVersion | n == fromIntegral msStrictatime = Strictatime | n == fromIntegral msActive = Active | n == fromIntegral msNouser = Nouser | otherwise = error ("(toEnum " ++ (show n) ++ ")::MountFlag: " ++ (show n) ++ " is outside of enumeration range") -- |DriverData specifies the filesystem dependent options to be used -- when mounting a filesystem; the content of DriverData is passed -- directly to the filesystem driver. newtype DriverData = DriverData ByteString deriving Eq noData :: DriverData noData = DriverData empty combineBitMasks :: (Enum a, Bits b) => [a] -> b combineBitMasks = foldl (.|.) 0 . map (fromIntegral . fromEnum) -- |UmountFlag specifies a filesystem independent option to be used -- when umounting a filesystem data UmountFlag = Force | Detach | Expire | Nofollow deriving (Eq, Read, Show) instance Enum UmountFlag where fromEnum Force = fromIntegral mntForce fromEnum Detach = fromIntegral mntDetach fromEnum Expire = fromIntegral mntExpire fromEnum Nofollow = fromIntegral umountNofollow toEnum n | n == (fromIntegral mntForce) = Force | n == (fromIntegral mntDetach) = Detach | n == (fromIntegral mntExpire) = Expire | n == (fromIntegral umountNofollow) = Nofollow | otherwise = error ("(toEnum " ++ (show n) ++ ")::UmountFlag: " ++ (show n) ++ " is outside of enumeration range") #enum CInt, , MNT_FORCE, MNT_DETACH, MNT_EXPIRE, UMOUNT_NOFOLLOW #enum CULong, , MS_RDONLY, MS_NOSUID, MS_NODEV, MS_NOEXEC, MS_SYNCHRONOUS, MS_REMOUNT, MS_MANDLOCK, MS_DIRSYNC, MS_NOATIME, MS_NODIRATIME, MS_BIND, MS_MOVE, MS_REC, MS_SILENT, MS_POSIXACL, MS_UNBINDABLE, MS_PRIVATE, MS_SLAVE, MS_SHARED, MS_RELATIME, MS_KERNMOUNT, MS_I_VERSION, MS_STRICTATIME, MS_ACTIVE, MS_NOUSER