diff --git a/System/Posix/Redirect.hs b/System/Posix/Redirect.hs
--- a/System/Posix/Redirect.hs
+++ b/System/Posix/Redirect.hs
@@ -1,4 +1,5 @@
-{-# LANGUAGE EmptyDataDecls, ForeignFunctionInterface #-}
+{-# LANGUAGE EmptyDataDecls #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
 
 {- |
 Module      : System.Posix.Redirect
@@ -34,20 +35,18 @@
     , unsafeRedirectWriteFd
     ) where
 
-import System.Posix.Types
-import System.Posix.IO
-import System.IO
-
-import Foreign
-import Foreign.C.Types
+import Control.Concurrent
+import Control.Exception
+import Control.Monad
 
 import Data.ByteString as BS
 
-import Control.Concurrent
-import Control.Exception
+import Foreign.C.Types
+import Foreign.Ptr
 
-dupTo_ :: Fd -> Fd -> IO ()
-dupTo_ a b = dupTo a b >>= \_ -> return ()
+import System.IO
+import System.Posix.IO
+import System.Posix.Types
 
 -- | @'unsafeRedirectFd' fd f@ executes the computation @f@, passing as
 -- an argument a handle which is the read end of a pipe that
@@ -56,24 +55,26 @@
 -- handles with this descriptor that have unflushed buffers, they will
 -- not flush to the old file descriptor, but the new file descriptor.
 unsafeRedirectWriteFd :: Fd -> IO a -> IO (ByteString, a)
-unsafeRedirectWriteFd fd f = do
-    -- setup
-    (rfd, wfd) <- createPipe
-    old <- dup fd
-    dupTo_ wfd fd
+unsafeRedirectWriteFd fd f = bracket setup (hClose . fst) $
+        \ (outHandle, (wfd, old)) -> do
     -- fork a thread to consume output
     outMVar <- newEmptyMVar
-    outHandle <- fdToHandle rfd
-    _ <- forkIO (BS.hGetContents outHandle >>= putMVar outMVar)
+    void $ forkIO (BS.hGetContents outHandle >>= putMVar outMVar)
     -- run the code
-    r <- f
-    -- cleanup
-    dupTo_ old fd
-    closeFd wfd
+    r <- f `finally` do
+        -- cleanup
+        void $ dupTo old fd
+        closeFd wfd
     -- wait for output
     out <- takeMVar outMVar
-    hClose outHandle
     return (out, r)
+  where
+    setup = do
+        (rfd, wfd) <- createPipe
+        old <- dup fd
+        void $ dupTo wfd fd
+        outHandle <- fdToHandle rfd
+        return (outHandle, (wfd, old))
 
 -- | @'redirectWriteHandle' oldFd oldHandle oldCHandle f@ executes the
 -- computation @f@, passing as an argument a handle which is the read
@@ -84,11 +85,11 @@
 redirectWriteHandle oldFd oldHandle cOldHandle f = do
     hFlush oldHandle
     hFlush stdout
-    _ <- c_fflush cOldHandle
+    void $ c_fflush cOldHandle
     unsafeRedirectWriteFd oldFd $ do
         r <- f
         hFlush oldHandle
-        _ <- c_fflush cOldHandle
+        void $ c_fflush cOldHandle
         return r
 
 -- | @'redirectStdout' f@ redirects standard output during the execution
diff --git a/system-posix-redirect.cabal b/system-posix-redirect.cabal
--- a/system-posix-redirect.cabal
+++ b/system-posix-redirect.cabal
@@ -1,39 +1,39 @@
-Name:               system-posix-redirect
-Version:            1.1
-Synopsis:           A toy module that allows you to temporarily redirect
-                    a program's stdout.
-Description:        Due to the design of POSIX, it is possible to
-                    temporarily overload the file descriptors
-                    corresponding to stdout and stderr to point to an
-                    arbitrary pipe.  It is, however, tricky to get
-                    right.  This module gets it right, as far as such
-                    a terrible hack can be made right.  It can be used
-                    to make misbehaving third-party C libraries stop
-                    spewing to standard output. Warning: the module
-                    author has concluded that due to lack of
-                    portability, this module should not be used in any
-                    serious sytem.  But, for those who like living
-                    dangerously...
-License:            BSD3
-License-file:       LICENSE
-Author:             Galois Inc.
-Maintainer:         ezyang@galois.com
-Copyright:          (c) 2010 Galois Inc.
-Category:           System
-Build-type:         Simple
-Extra-source-files: include/*.h
-                    cbits/*.c
-Cabal-Version: >= 1.6
+name: system-posix-redirect
+version: 1.1.0.1
+synopsis: A toy module to temporarily redirect a program's stdout.
+description:
+    Due to the design of POSIX, it is possible to temporarily overload the
+    file descriptors corresponding to stdout and stderr to point to an
+    arbitrary pipe. It is, however, tricky to get right. This module gets
+    it right, as far as such a terrible hack can be made right. It can be
+    used to make misbehaving third-party C libraries stop spewing to
+    standard output. Warning: the module author has concluded that due to
+    lack of portability, this module should not be used in any serious
+    sytem. But, for those who like living dangerously...
+license: BSD3
+license-file: LICENSE
+author: Galois Inc., Liyang HU
+maintainer: system-posix-redirect@liyang.hu
+copyright: (c) 2010 Galois Inc, 2013 Liyang HU
+category: System
+build-type: Simple
+extra-source-files:
+    include/hsredirect.h
+    cbits/hsredirect.c
+cabal-version: >= 1.6
 
-Source-Repository head
-  Type:     git
-  Location: https://github.com/liyang/system-posix-redirect
+source-repository head
+    type: git
+    location: https://github.com/liyang/system-posix-redirect
 
-Library
-  Exposed-modules:      System.Posix.Redirect
-  Extensions:           ForeignFunctionInterface,
-                        EmptyDataDecls
-  Build-depends:        base >= 4 && < 5, bytestring >= 0.9, unix >= 2.4.0
-  C-sources:            cbits/hsredirect.c
-  Include-dirs:         include
-  Install-includes:     include/hsredirect.h
+library
+    exposed-modules:
+        System.Posix.Redirect
+    build-depends:
+        base >= 4 && < 5,
+        bytestring >= 0.9,
+        unix >= 2.4.0
+    ghc-options: -Wall
+    c-sources: cbits/hsredirect.c
+    include-dirs: include
+    install-includes: include/hsredirect.h
