2012-07-19 16:51:55 +00:00
|
|
|
{- Interface to mtab (and fstab)
|
|
|
|
-
|
|
|
|
- Derived from hsshellscript, originally written by
|
|
|
|
- Volker Wysk <hsss@volker-wysk.de>
|
2012-07-20 00:38:58 +00:00
|
|
|
-
|
|
|
|
- Modified to support BSD and Mac OS X by
|
|
|
|
- Joey Hess <joey@kitenet.net>
|
2012-07-19 16:51:55 +00:00
|
|
|
-
|
|
|
|
- Licensed under the GNU LGPL version 2.1 or higher.
|
|
|
|
-}
|
|
|
|
|
|
|
|
{-# LANGUAGE ForeignFunctionInterface #-}
|
|
|
|
|
|
|
|
module Utility.Mounts (
|
|
|
|
Mntent(..),
|
2012-07-20 00:38:58 +00:00
|
|
|
getMounts
|
2012-07-19 16:51:55 +00:00
|
|
|
) where
|
|
|
|
|
|
|
|
import Control.Monad
|
|
|
|
import Foreign
|
|
|
|
import Foreign.C
|
|
|
|
import GHC.IO hiding (finally, bracket)
|
|
|
|
import Prelude hiding (catch)
|
|
|
|
|
2012-07-20 00:38:58 +00:00
|
|
|
#include "libmounts.h"
|
2012-07-19 16:51:55 +00:00
|
|
|
|
2012-07-20 00:38:58 +00:00
|
|
|
{- This is a stripped down mntent, containing only
|
|
|
|
- fields available everywhere. -}
|
2012-07-19 16:51:55 +00:00
|
|
|
data Mntent = Mntent
|
|
|
|
{ mnt_fsname :: String
|
|
|
|
, mnt_dir :: String
|
|
|
|
, mnt_type :: String
|
2012-07-20 01:25:26 +00:00
|
|
|
} deriving (Read, Show, Eq, Ord)
|
2012-07-19 16:51:55 +00:00
|
|
|
|
2012-07-20 00:38:58 +00:00
|
|
|
getMounts :: IO [Mntent]
|
|
|
|
getMounts = do
|
|
|
|
h <- c_mounts_start
|
2012-07-19 16:51:55 +00:00
|
|
|
when (h == nullPtr) $
|
2012-07-20 00:38:58 +00:00
|
|
|
throwErrno "getMounts"
|
2012-07-19 16:51:55 +00:00
|
|
|
mntent <- getmntent h []
|
2012-07-20 00:38:58 +00:00
|
|
|
_ <- c_mounts_end h
|
2012-07-19 16:51:55 +00:00
|
|
|
return mntent
|
|
|
|
|
|
|
|
where
|
2012-07-20 00:38:58 +00:00
|
|
|
getmntent h c = do
|
|
|
|
ptr <- c_mounts_next h
|
2012-07-19 16:51:55 +00:00
|
|
|
if (ptr == nullPtr)
|
2012-07-20 00:38:58 +00:00
|
|
|
then return $ reverse c
|
2012-07-19 16:51:55 +00:00
|
|
|
else do
|
|
|
|
mnt_fsname_str <- #{peek struct mntent, mnt_fsname} ptr >>= peekCString
|
|
|
|
mnt_dir_str <- #{peek struct mntent, mnt_dir} ptr >>= peekCString
|
|
|
|
mnt_type_str <- #{peek struct mntent, mnt_type} ptr >>= peekCString
|
|
|
|
let ent = Mntent
|
|
|
|
{ mnt_fsname = mnt_fsname_str
|
|
|
|
, mnt_dir = mnt_dir_str
|
|
|
|
, mnt_type = mnt_type_str
|
|
|
|
}
|
2012-07-20 00:38:58 +00:00
|
|
|
getmntent h (ent:c)
|
2012-07-19 16:51:55 +00:00
|
|
|
|
2012-07-20 19:07:48 +00:00
|
|
|
{- Using unsafe imports because the C functions are belived to never block.
|
|
|
|
- Note that getmntinfo is called with MNT_NOWAIT to avoid possibly blocking;
|
|
|
|
- while getmntent only accesses a file in /etc (or /proc) that should not
|
|
|
|
- block. -}
|
2012-07-20 00:38:58 +00:00
|
|
|
foreign import ccall unsafe "libmounts.h mounts_start" c_mounts_start
|
|
|
|
:: IO (Ptr ())
|
|
|
|
foreign import ccall unsafe "libmounts.h mounts_next" c_mounts_next
|
|
|
|
:: Ptr () -> IO (Ptr ())
|
|
|
|
foreign import ccall unsafe "libmounts.h mounts_end" c_mounts_end
|
|
|
|
:: Ptr () -> IO CInt
|