diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,7 +1,7 @@
 #!/usr/bin/runhaskell
 
 import Distribution.Simple
-import System.Cmd
+import System.Process
 import System.Exit
 
 main = defaultMainWithHooks simpleUserHooks
diff --git a/System/Unix/Chroot.hs b/System/Unix/Chroot.hs
--- a/System/Unix/Chroot.hs
+++ b/System/Unix/Chroot.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE CPP #-}
 -- | This module, except for useEnv, is copied from the build-env package.
 module System.Unix.Chroot
     ( fchroot
@@ -7,8 +8,9 @@
     -- , forceList'
     ) where
 
-import Control.Exception (finally, evaluate)
-
+import Control.Exception (evaluate)
+import Control.Monad.Catch (MonadMask, finally)
+import Control.Monad.Trans (MonadIO, liftIO)
 import qualified Data.ByteString.Char8 as B
 import qualified Data.ByteString.Lazy.Char8 as L
 import Foreign.C.Error
@@ -41,13 +43,17 @@
 -- chroot and working directory of all the threads in the process,
 -- so...
 -- NOTE: will throw IOError if internal chroot fails
-fchroot :: FilePath -> IO a -> IO a
+fchroot :: (MonadIO m, MonadMask m) => FilePath -> m a -> m a
 fchroot path action =
-    do origWd <- getWorkingDirectory
-       rootFd <- openFd "/" ReadOnly Nothing defaultFileFlags
-       chroot path
-       changeWorkingDirectory "/"
-       action `finally` (breakFree origWd rootFd)
+    do origWd <- liftIO $ getWorkingDirectory
+#if MIN_VERSION_unix(2,8,0)
+       rootFd <- liftIO $ openFd "/" ReadOnly defaultFileFlags
+#else
+       rootFd <- liftIO $ openFd "/" ReadOnly Nothing defaultFileFlags
+#endif
+       liftIO $ chroot path
+       liftIO $ changeWorkingDirectory "/"
+       action `finally` (liftIO $ breakFree origWd rootFd)
     where
       breakFree origWd rootFd =
           do changeWorkingDirectoryFd rootFd
@@ -58,15 +64,15 @@
 -- |The ssh inside of the chroot needs to be able to talk to the
 -- running ssh-agent.  Therefore we mount --bind the ssh agent socket
 -- dir inside the chroot (and umount it when we exit the chroot.
-useEnv :: FilePath -> (a -> IO a) -> IO a -> IO a
+useEnv :: (MonadIO m, MonadMask m) => FilePath -> (a -> m a) -> m a -> m a
 useEnv rootPath force action =
     do -- In order to minimize confusion, this QIO message is output
        -- at default quietness.  If you want to suppress it while seeing
        -- the output from your action, you need to say something like
        -- quieter (+ 1) (useEnv (quieter (\x->x-1) action))
-       sockPath <- getEnv "SSH_AUTH_SOCK"
-       home <- getEnv "HOME"
-       copySSH home
+       sockPath <- liftIO $ getEnv "SSH_AUTH_SOCK"
+       home <- liftIO $ getEnv "HOME"
+       liftIO $ copySSH home
        -- We need to force the output before we exit the changeroot.
        -- Otherwise we lose our ability to communicate with the ssh
        -- agent and we get errors.
@@ -75,18 +81,19 @@
       copySSH Nothing = return ()
       copySSH (Just home) =
           -- Do NOT preserve ownership, files must be owned by root.
+          createDirectoryIfMissing True (rootPath ++ "/root") >>
           run "/usr/bin/rsync" ["-rlptgDHxS", "--delete", home ++ "/.ssh/", rootPath ++ "/root/.ssh"]
+      withSock :: (MonadIO m, MonadMask m) => Maybe FilePath -> m a -> m a
       withSock Nothing action = action
       withSock (Just sockPath) action =
           withMountBind dir (rootPath ++ dir) action
           where dir = dropTrailingPathSeparator (dropFileName sockPath)
+      withMountBind :: (MonadIO m, MonadMask m) => FilePath -> FilePath -> m a -> m a
       withMountBind toMount mountPoint action =
-          do createDirectoryIfMissing True mountPoint
-             run "/bin/mount" ["--bind", escapePathForMount toMount, escapePathForMount mountPoint]
-             result <- action
-             run "/bin/umount" [escapePathForMount mountPoint]
-             return result
-      escapePathForMount = id	-- FIXME - Path arguments should be escaped
+          (do liftIO $ createDirectoryIfMissing True mountPoint
+              liftIO $ run "/bin/mount" ["--bind", escapePathForMount toMount, escapePathForMount mountPoint]
+              action) `finally` (liftIO $ run "/bin/umount" [escapePathForMount mountPoint])
+      escapePathForMount = id   -- FIXME - Path arguments should be escaped
 
       run cmd args =
           do (code, out, err) <- readProcessWithExitCode cmd args ""
diff --git a/System/Unix/Crypt.hs b/System/Unix/Crypt.hs
--- a/System/Unix/Crypt.hs
+++ b/System/Unix/Crypt.hs
@@ -4,7 +4,7 @@
 -- Module      :  System.Unix.Crypt
 -- Copyright   :  (c) 2010
 -- License     :  BSD3
--- 
+--
 -- Maintainer  :  jeremy@seereason.com
 -- Stability   :  provisional
 -- Portability :  non-portable (requires POSIX)
@@ -13,7 +13,7 @@
 --
 -----------------------------------------------------------------------------
 
-module System.Unix.Crypt 
+module System.Unix.Crypt
     ( crypt
     )
     where
@@ -23,7 +23,7 @@
 foreign import ccall unsafe "unistd.h crypt"
   c_crypt :: CString -> CString -> IO CString
 
--- | calls crypt(3) 
+-- | calls crypt(3)
 crypt :: String -- ^ key
       -> String -- ^ salt
       -> IO String -- ^ encrypted password
diff --git a/System/Unix/Directory.hs b/System/Unix/Directory.hs
--- a/System/Unix/Directory.hs
+++ b/System/Unix/Directory.hs
@@ -12,7 +12,7 @@
 
 import Control.Exception
 import Data.List (isSuffixOf)
-import System.Cmd
+import System.Process
 import System.Directory
 import System.Exit
 import System.FilePath
@@ -28,7 +28,7 @@
     do
       status <- getSymbolicLinkStatus path
       case isDirectory status of
-        True -> 
+        True ->
             do
               subs <- getDirectoryContents path >>=
                       return . map (path </>) . filter (not . flip elem [".", ".."]) >>=
@@ -84,7 +84,7 @@
 --	when you are inside a chroot.
 removeRecursiveSafely :: FilePath -> IO ()
 removeRecursiveSafely path =
-    traverse path removeFile removeDirectory umount
+    System.Unix.Directory.traverse path removeFile removeDirectory umount
     where
       umount path =
           do
@@ -102,7 +102,7 @@
 -- unmounts anything it finds mounted.  Note that this can be much
 -- slower than Mount.umountBelow, use that instead.
 unmountRecursiveSafely path =
-    traverse path noOp noOp umount
+    System.Unix.Directory.traverse path noOp noOp umount
     where
       noOp _ = return ()
       umount path =
@@ -134,7 +134,7 @@
 
 -- |temporarily change the working directory to |dir| while running |action|
 withWorkingDirectory :: FilePath -> IO a -> IO a
-withWorkingDirectory dir action = 
+withWorkingDirectory dir action =
     bracket getCurrentDirectory setCurrentDirectory (\ _ -> setCurrentDirectory dir >> action)
 
 -- |create a temporary directory, run the action, remove the temporary directory
@@ -153,7 +153,7 @@
   c_mkdtemp :: CString -> IO CString
 
 mkdtemp :: FilePath -> IO FilePath
-mkdtemp template = 
+mkdtemp template =
       withCString (if "XXXXXX" `isSuffixOf` template then template else (template ++ "XXXXXX")) $ \ ptr -> do
         cname <- throwErrnoIfNull "mkdtemp" (c_mkdtemp ptr)
         name <- peekCString cname
diff --git a/System/Unix/FilePath.hsc b/System/Unix/FilePath.hsc
--- a/System/Unix/FilePath.hsc
+++ b/System/Unix/FilePath.hsc
@@ -3,7 +3,7 @@
 -- | The function splitFileName is taken from missingh, at the moment
 -- missingh will not build under sid.
 
-module System.Unix.FilePath 
+module System.Unix.FilePath
     (dirName,
      baseName,
      realpath,
diff --git a/System/Unix/Files.hs b/System/Unix/Files.hs
--- a/System/Unix/Files.hs
+++ b/System/Unix/Files.hs
@@ -10,7 +10,7 @@
 forceSymbolicLink :: FilePath -> FilePath -> IO ()
 forceSymbolicLink target linkName =
     createSymbolicLink target linkName `catch`
-      (\e -> if isAlreadyExistsError e 
+      (\e -> if isAlreadyExistsError e
              then do removeLink linkName
                      createSymbolicLink target linkName
              else ioError e)
diff --git a/System/Unix/KillByCwd.hs b/System/Unix/KillByCwd.hs
new file mode 100644
--- /dev/null
+++ b/System/Unix/KillByCwd.hs
@@ -0,0 +1,44 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+-- |A place to collect and hopefully retire all the random ways of
+-- running shell commands that have accumulated over the years.
+module System.Unix.KillByCwd
+    ( killByCwd
+    ) where
+
+import Control.Exception (catch)
+import Control.Monad (liftM, filterM)
+import Data.Char (isDigit)
+import Data.List (isPrefixOf)
+import Prelude hiding (catch)
+import System.Directory (getDirectoryContents)
+import System.Posix.Files (readSymbolicLink)
+import System.Posix.Signals (signalProcess, sigTERM)
+
+{-
+NOTE:
+
++ We should make sure this works if we are inside a chroot.
+
++ path needs to be absolute or we might kill processes living in
+  similarly named, but different directories.
+
++ path is an canoncialised, absolute path, such as what realpath returns
+
+-}
+-- | Kill the processes whose working directory is in or under the
+-- given directory.
+killByCwd :: FilePath -> IO [(String, Maybe String)]
+killByCwd path =
+    do pids <- liftM (filter (all isDigit)) (getDirectoryContents "/proc")
+       cwdPids <- filterM (isCwd path) pids
+       exePaths <- mapM exePath cwdPids
+       mapM_ kill cwdPids
+       return (zip cwdPids exePaths)
+    where
+      isCwd :: FilePath -> String -> IO Bool
+      isCwd cwd pid =
+          (liftM (isPrefixOf cwd) (readSymbolicLink ("/proc/" ++ pid ++"/cwd"))) `catch` (\ (_ :: IOError) -> return False)
+      exePath :: String -> IO (Maybe String)
+      exePath pid = (readSymbolicLink ("/proc/" ++ pid ++"/exe") >>= return . Just) `catch` (\ (_ :: IOError) -> return Nothing)
+      kill :: String -> IO ()
+      kill pidStr = signalProcess sigTERM (read pidStr)
diff --git a/System/Unix/Misc.hs b/System/Unix/Misc.hs
--- a/System/Unix/Misc.hs
+++ b/System/Unix/Misc.hs
@@ -11,13 +11,14 @@
 import Data.ByteString.Lazy.Char8 (empty, readFile, writeFile)
 import Data.Digest.Pure.MD5 (md5)
 import Data.Maybe
-import System.Cmd
+import System.Process
 import System.Directory
 import System.Exit
 import System.IO
 import System.Posix.Files
 import System.Process
 
+-- | Deprecated: Use @Data.ByteString.Lazy.Char8.readFile path >>= return . show . Data.Digest.Pure.MD5.md5@
 {-# DEPRECATED md5sum "Use Data.ByteString.Lazy.Char8.readFile path >>= return . show . Data.Digest.Pure.MD5.md5" #-}
 md5sum :: FilePath -> IO String
 md5sum path = Data.ByteString.Lazy.Char8.readFile path >>= return . show . md5
@@ -33,6 +34,7 @@
         _ -> error ("Error running 'md5sum " ++ path ++ "'")
 -}
 
+-- | Deprecated: Use @Data.ByteString.Lazy.Char8.readFile path >>= Data.ByteString.Lazy.Char8.writeFile (path ++ \".gz\")@
 {-# DEPRECATED gzip "Use Data.ByteString.Lazy.Char8.readFile path >>= Data.ByteString.Lazy.Char8.writeFile (path ++ \".gz\")" #-}
 gzip :: FilePath -> IO ()
 gzip path = Data.ByteString.Lazy.Char8.readFile path >>= Data.ByteString.Lazy.Char8.writeFile (path ++ ".gz")
diff --git a/System/Unix/Mount.hs b/System/Unix/Mount.hs
--- a/System/Unix/Mount.hs
+++ b/System/Unix/Mount.hs
@@ -1,10 +1,16 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving, ScopedTypeVariables #-}
 -- |functions for mounting, umounting, parsing \/proc\/mounts, etc
-module System.Unix.Mount 
-    (umountBelow,	-- FilePath -> IO [(FilePath, (String, String, ExitCode))]
-     umount,		-- [String] -> IO (String, String, ExitCode)
-     isMountPoint)	-- FilePath -> IO Bool
-    where
+module System.Unix.Mount
+    ( umountBelow       -- FilePath -> IO [(FilePath, (String, String, ExitCode))]
+    , umount            -- [String] -> IO (String, String, ExitCode)
+    , isMountPoint      -- FilePath -> IO Bool
 
+    , withMount
+    , WithProcAndSys(runWithProcAndSys)
+    , withProcAndSys
+    , withTmp
+    ) where
+
 -- Standard GHC modules
 
 import Control.Monad
@@ -16,6 +22,21 @@
 import System.Posix.Files
 import System.Process (readProcessWithExitCode)
 
+import Control.Applicative (Applicative)
+import Control.Exception (catch)
+import Control.Monad.Catch (bracket, MonadCatch, MonadMask)
+import Control.Monad.Trans (MonadTrans, lift, liftIO, MonadIO)
+-- import Control.Monad.Trans.Except ({- ExceptT instances -})
+import Data.ByteString.Lazy as L (ByteString, empty)
+import GHC.IO.Exception (IOErrorType(OtherError))
+import System.Directory (createDirectoryIfMissing)
+import System.Exit (ExitCode(ExitFailure, ExitSuccess))
+import System.FilePath ((</>))
+import System.IO (hPutStrLn, stderr)
+import System.IO.Error
+import System.Process (CreateProcess, proc)
+import System.Process.ListLike (readCreateProcess, showCreateProcessForUser)
+
 -- Local Modules
 
 -- In ghc610 readFile "/proc/mounts" hangs.  Use this instead.
@@ -78,7 +99,7 @@
 unescape ('\\':'1':'3':'4':rest) = '\\' : (unescape rest)
 unescape (c:rest) = c : (unescape rest)
 
--- |'escape' - \/proc\/mount stytle string escaper
+-- |'escape' - \/proc\/mount style string escaper
 escape :: String -> String
 escape [] = []
 escape (' ':rest)  = ('\\':'0':'4':'0':escape rest)
@@ -115,3 +136,57 @@
             -- It is hard to know what is going on if . or .. don't exist.
             -- Assume we are seeing some sort of mount point.
             return True
+
+readProcess :: CreateProcess -> L.ByteString -> IO L.ByteString
+readProcess p input = do
+  (code, out, _err) <- readCreateProcess p input :: IO (ExitCode, L.ByteString, L.ByteString)
+  case code of
+    ExitFailure n -> ioError (mkIOError OtherError (showCreateProcessForUser p ++ " -> " ++ show n) Nothing Nothing)
+    ExitSuccess -> return out
+
+-- | Do an IO task with a file system remounted using mount --bind.
+-- This was written to set up a build environment.
+withMount :: (MonadIO m, MonadMask m) => FilePath -> FilePath -> m a -> m a
+withMount directory mountpoint task =
+    bracket pre (\ _ -> post) (\ _ -> task)
+    where
+      mount = proc "mount" ["--bind", directory, mountpoint]
+      umount = proc "umount" [mountpoint]
+      umountLazy = proc "umount" ["-l", mountpoint]
+
+      pre = liftIO $ do -- hPutStrLn stderr $ "mounting /proc at " ++ show mountpoint
+                        createDirectoryIfMissing True mountpoint
+                        readProcess mount L.empty
+
+      post = liftIO $ do -- hPutStrLn stderr $ "unmounting /proc at " ++ show mountpoint
+                         readProcess umount L.empty
+                           `catch` (\ (e :: IOError) ->
+                                        do hPutStrLn stderr ("Exception unmounting " ++ mountpoint ++ ", trying -l: " ++ show e)
+                                           readProcess umountLazy L.empty)
+
+-- | Monad transformer to ensure that /proc and /sys are mounted
+-- during a computation.
+newtype WithProcAndSys m a = WithProcAndSys { runWithProcAndSys :: m a } deriving (Functor, Monad, Applicative)
+
+instance MonadTrans WithProcAndSys where
+    lift = WithProcAndSys
+
+instance MonadIO m => MonadIO (WithProcAndSys m) where
+    liftIO task = WithProcAndSys (liftIO task)
+
+-- | Mount /proc and /sys in the specified build root and execute a
+-- task.  Typically, the task would start with a chroot into the build
+-- root.  If the build root given is "/" it is assumed that the file
+-- systems are already mounted, no mounting or unmounting is done.
+withProcAndSys :: (MonadIO m, MonadMask m) => FilePath -> WithProcAndSys m a -> m a
+withProcAndSys "/" task = runWithProcAndSys task
+withProcAndSys root task = do
+  exists <- liftIO $ doesDirectoryExist root
+  case exists of
+    True -> withMount "/proc" (root </> "proc") $ withMount "/sys" (root </> "sys") $ runWithProcAndSys task
+    False -> liftIO $ ioError $ mkIOError doesNotExistErrorType "chroot directory does not exist" Nothing (Just root)
+
+-- | Do an IO task with /tmp remounted.  This could be used
+-- to share /tmp with a build root.
+withTmp :: (MonadIO m, MonadMask m) => FilePath -> m a -> m a
+withTmp root task = withMount "/tmp" (root </> "tmp") task
diff --git a/System/Unix/Process.hs b/System/Unix/Process.hs
deleted file mode 100644
--- a/System/Unix/Process.hs
+++ /dev/null
@@ -1,89 +0,0 @@
--- | Variations of the readProcess and readProcessWithExitCode functions
--- from System.Process which read and write ByteStrings and have an
--- extra argument to modify the CreateProcess value before the process
--- is started.
-module System.Unix.Process
-    ( readProcess
-    , readProcessWithExitCode
-    ) where
-
-import Control.Concurrent (newEmptyMVar, forkIO, putMVar, takeMVar)
-import qualified Control.Exception as C
-import Control.Monad (when)
-import qualified Data.ByteString.Lazy.Char8 as B
-import GHC.IO.Exception (IOErrorType(OtherError))
-import System.Exit (ExitCode(..))
-import System.IO (hFlush, hClose)
-import System.IO.Error (mkIOError)
-import System.Process (CreateProcess(std_in, std_out, std_err, cwd), createProcess, waitForProcess, proc, StdStream(CreatePipe, Inherit), showCommandForUser)
-
-readProcessWithExitCode
-    :: FilePath                         -- ^ command to run
-    -> [String]                         -- ^ any arguments
-    -> (CreateProcess -> CreateProcess) -- ^ Modify process with this - use id for System.Process.readProcessWithExitCode behavior
-    -> B.ByteString                     -- ^ standard input
-    -> IO (ExitCode, B.ByteString, B.ByteString) -- ^ exitcode, stdout, stderr
-readProcessWithExitCode cmd args modify input = do
-    let modify' p = modify (p {std_in  = CreatePipe, std_out = CreatePipe, std_err = CreatePipe })
-
-    (Just inh, Just outh, Just errh, pid) <-
-        createProcess (modify' (proc cmd args))
-
-    outMVar <- newEmptyMVar
-
-    -- fork off a thread to start consuming stdout
-    out  <- B.hGetContents outh
-    _ <- forkIO $ C.evaluate (B.length out) >> putMVar outMVar ()
-
-    -- fork off a thread to start consuming stderr
-    err  <- B.hGetContents errh
-    _ <- forkIO $ C.evaluate (B.length err) >> putMVar outMVar ()
-
-    -- now write and flush any input
-    when (not (B.null input)) $ do B.hPutStr inh input; hFlush inh
-    hClose inh -- done with stdin
-
-    -- wait on the output
-    takeMVar outMVar
-    takeMVar outMVar
-    hClose outh
-    hClose errh
-
-    -- wait on the process
-    ex <- waitForProcess pid
-
-    return (ex, out, err)
-
-readProcess
-    :: FilePath		-- ^ command to run
-    -> [String]		-- ^ any arguments
-    -> (CreateProcess -> CreateProcess) -- ^ modifies CreateProcess before passing to createProcess
-    -> B.ByteString	-- ^ standard input
-    -> IO B.ByteString	-- ^ stdout
-readProcess cmd args modify input = do
-    let modify' p = modify (p {std_in  = CreatePipe, std_out = CreatePipe, std_err = Inherit })
-    (Just inh, Just outh, _, pid) <-
-        createProcess (modify' (proc cmd args))
-
-    -- fork off a thread to start consuming the output
-    output  <- B.hGetContents outh
-    outMVar <- newEmptyMVar
-    _ <- forkIO $ C.evaluate (B.length output) >> putMVar outMVar ()
-
-    -- now write and flush any input
-    when (not (B.null input)) $ do B.hPutStr inh input; hFlush inh
-    hClose inh -- done with stdin
-
-    -- wait on the output
-    takeMVar outMVar
-    hClose outh
-
-    -- wait on the process
-    ex <- waitForProcess pid
-
-    case ex of
-      ExitSuccess   -> return output
-      ExitFailure r ->
-          ioError (mkIOError OtherError ("readProcess: " ++ showCommandForUser cmd args ++
-                                                             " (exit " ++ show r ++ ")")
-                   Nothing Nothing)
diff --git a/System/Unix/SpecialDevice.hs b/System/Unix/SpecialDevice.hs
--- a/System/Unix/SpecialDevice.hs
+++ b/System/Unix/SpecialDevice.hs
@@ -2,30 +2,30 @@
 -- | Construct an ADT representing block and character devices
 -- (but mostly block devices) by interpreting the contents of
 -- the Linux sysfs filesystem.
-module System.Unix.SpecialDevice 
+module System.Unix.SpecialDevice
     (SpecialDevice,
-     sysMountPoint,	-- IO String
-     ofNode,		-- FilePath -> IO (Maybe SpecialDevice)
-     ofNodeStatus,	-- FileStatus -> Maybe SpecialDevice
-     ofPath,		-- FilePath -> IO (Maybe SpecialDevice)
-     rootPart,		-- IO (Maybe SpecialDevice)
-     ofDevNo,		-- (DeviceID -> SpecialDevice) -> Int -> SpecialDevice
-     ofSysName,		-- String -> IO (Maybe SpecialDevice)
-     ofSysPath,		-- (DeviceID -> SpecialDevice) -> FilePath -> IO (Maybe SpecialDevice)
-     toDevno,		-- SpecialDevice -> Int
-     --major,		-- SpecialDevice -> Int
-     --minor,		-- SpecialDevice -> Int
-     ofMajorMinor,	-- (DeviceID -> SpecialDevice) -> Int -> Int -> SpecialDevice
-     node,		-- SpecialDevice -> IO (Maybe FilePath)
-     nodes,		-- SpecialDevice -> IO [FilePath]
-     sysName,		-- SpecialDevice -> IO (Maybe String)
-     splitPart,		-- String -> (String, Int)
-     sysDir,		-- SpecialDevice -> IO (Maybe FilePath)
-     diskOfPart,	-- SpecialDevice -> IO (Maybe SpecialDevice)
-     getAllDisks,	-- IO [SpecialDevice]
-     getAllPartitions,	-- IO [SpecialDevice]
-     getAllCdroms,	-- IO [SpecialDevice]
-     getAllRemovable,	-- IO [SpecialDevice]
+     sysMountPoint,     -- IO String
+     ofNode,            -- FilePath -> IO (Maybe SpecialDevice)
+     ofNodeStatus,      -- FileStatus -> Maybe SpecialDevice
+     ofPath,            -- FilePath -> IO (Maybe SpecialDevice)
+     rootPart,          -- IO (Maybe SpecialDevice)
+     ofDevNo,           -- (DeviceID -> SpecialDevice) -> Int -> SpecialDevice
+     ofSysName,         -- String -> IO (Maybe SpecialDevice)
+     ofSysPath,         -- (DeviceID -> SpecialDevice) -> FilePath -> IO (Maybe SpecialDevice)
+     toDevno,           -- SpecialDevice -> Int
+     --major,           -- SpecialDevice -> Int
+     --minor,           -- SpecialDevice -> Int
+     ofMajorMinor,      -- (DeviceID -> SpecialDevice) -> Int -> Int -> SpecialDevice
+     node,              -- SpecialDevice -> IO (Maybe FilePath)
+     nodes,             -- SpecialDevice -> IO [FilePath]
+     sysName,           -- SpecialDevice -> IO (Maybe String)
+     splitPart,         -- String -> (String, Int)
+     sysDir,            -- SpecialDevice -> IO (Maybe FilePath)
+     diskOfPart,        -- SpecialDevice -> IO (Maybe SpecialDevice)
+     getAllDisks,       -- IO [SpecialDevice]
+     getAllPartitions,  -- IO [SpecialDevice]
+     getAllCdroms,      -- IO [SpecialDevice]
+     getAllRemovable,   -- IO [SpecialDevice]
 --     toDevName,
 --     getBlkidAlist,
 --     getBlkidInfo,
@@ -78,7 +78,7 @@
         (Just . BlockDevice . specialDeviceID $ status) else
         if isCharacterDevice status then
             (Just . CharacterDevice . specialDeviceID $ status) else
-            Nothing    
+            Nothing
 
 ofSysName :: String -> IO (Maybe SpecialDevice)
 ofSysName name =
@@ -144,7 +144,7 @@
 sysName dev = sysDir dev >>= return . maybe Nothing (Just . basename)
 
 sysDir :: SpecialDevice -> IO (Maybe FilePath)
-sysDir dev@(BlockDevice _) = 
+sysDir dev@(BlockDevice _) =
     do
       (pairs' :: [(FilePath, FileStatus)]) <- directory_find False (sysMountPoint ++ "/block")
       let (paths :: [FilePath]) = map fst . filter isDev $ pairs'
@@ -194,10 +194,10 @@
       x -> True
 
 getAllCdroms :: IO [SpecialDevice]
-getAllCdroms = cdromGroup >>= getDisksInGroup 
+getAllCdroms = cdromGroup >>= getDisksInGroup
 
 getAllRemovable :: IO [SpecialDevice]
-getAllRemovable = floppyGroup >>= getDisksInGroup 
+getAllRemovable = floppyGroup >>= getDisksInGroup
 
 -- ofNode "/dev/sda1" >>= maybe (return Nothing) sysDir >>= putStrLn . show
 -- -> Just "/sys/block/sda/sda1/dev"
diff --git a/Unixutils.cabal b/Unixutils.cabal
--- a/Unixutils.cabal
+++ b/Unixutils.cabal
@@ -1,29 +1,41 @@
 Name:           Unixutils
-Version:        1.50
+Version:        1.54.3
 License:        BSD3
 License-File:	COPYING
 Author:         Jeremy Shaw, David Fox
-Homepage:       http://src.seereason.com/haskell-unixutils
+Homepage:       https://github.com/seereason/haskell-unixutils.git
 Category:	System
 Synopsis:       A crude interface between Haskell and Unix-like operating systems
-Maintainer:     jeremy@n-heptane.com
+Maintainer:     David Fox <ddssff@gmail.com>
 Description:
  A collection of useful and mildly useful functions that you might
  expect to find in System.* which a heavy bias towards Unix-type operating systems.
 Build-type:	Simple
-Cabal-Version: >= 1.2
+Cabal-Version: >= 1.10
 
-Library 
-    Build-Depends:  base >= 4 && <5, bytestring, directory, filepath, process, pureMD5, regex-tdfa, unix, zlib
-    ghc-options:	-O2
+Library
+    Default-Language: Haskell2010
+    Build-Depends:
+      base >= 4.6 && <5,
+      bytestring,
+      directory,
+      exceptions,
+      filepath,
+      mtl,
+      process,
+      process-extras >= 0.3,
+      pureMD5,
+      regex-tdfa,
+      unix,
+      zlib
     Exposed-modules:
         System.Unix.Chroot,
         System.Unix.Crypt,
         System.Unix.Directory,
         System.Unix.FilePath,
+        System.Unix.KillByCwd,
         System.Unix.Misc,
         System.Unix.Mount,
-        System.Unix.Process,
         System.Unix.SpecialDevice,
         System.Unix.Files
     if !os(darwin)
