diff --git a/System/FileLock/Internal/Flock.hsc b/System/FileLock/Internal/Flock.hsc
--- a/System/FileLock/Internal/Flock.hsc
+++ b/System/FileLock/Internal/Flock.hsc
@@ -12,7 +12,7 @@
 import Foreign.C.Error
 import Foreign.C.Types
 import System.Posix.Files
-import System.Posix.IO (openFd, closeFd, defaultFileFlags, OpenMode(..))
+import System.Posix.IO (openFd, closeFd, defaultFileFlags, OpenMode(..), setFdOption, FdOption(..))
 import System.Posix.Types
 import Prelude
 
@@ -38,7 +38,17 @@
 unlock fd = closeFd fd
 
 open :: FilePath -> IO Fd
-open path = openFd path WriteOnly (Just stdFileMode) defaultFileFlags
+open path = do
+  fd <- openFd path WriteOnly (Just stdFileMode) defaultFileFlags
+  -- Ideally, we would open the file descriptor with CLOEXEC enabled, but since
+  -- unix 2.8 hasn't been released yet and we want backwards compatibility with
+  -- older releases, we set CLOEXEC after opening the file descriptor.  This
+  -- may seem like a race condition at first. However, since the lock is always
+  -- taken after CLOEXEC is set, the worst that can happen is that a child
+  -- process inherits the open FD in an unlocked state. While non-ideal from a
+  -- performance standpoint, it doesn't introduce any locking bugs.
+  setFdOption fd CloseOnExec True
+  return fd
 
 flock :: Fd -> Bool -> Bool -> IO Bool
 flock (Fd fd) exclusive block = do
diff --git a/filelock.cabal b/filelock.cabal
--- a/filelock.cabal
+++ b/filelock.cabal
@@ -2,7 +2,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                filelock
-version:             0.1.1.2
+version:             0.1.1.3
 synopsis:            Portable interface to file locking (flock / LockFileEx)
 description:         This package provides an interface to Windows and Unix
                      file locking functionalities.
@@ -39,6 +39,10 @@
   type:               exitcode-stdio-1.0
   hs-source-dirs:     tests
   main-is:            test.hs
-  build-depends:      filelock, process, async, base
+  build-depends:      filelock, process >= 1.2.1.0, async, base
   ghc-options:        -threaded
   default-language:   Haskell2010
+
+source-repository head
+  type: git
+  location: https://github.com/takano-akio/filelock.git
diff --git a/tests/lock.log.expected b/tests/lock.log.expected
--- a/tests/lock.log.expected
+++ b/tests/lock.log.expected
@@ -1,12 +1,12 @@
 took shared lock
 took shared lock
+releasing shared lock
 lock not available
 took shared lock
-released shared lock
-released shared lock
-released shared lock
+releasing shared lock
+releasing shared lock
 took exclusive lock
-released exclusive lock
+releasing exclusive lock
 took shared lock
-released shared lock
+releasing shared lock
 lock was available
diff --git a/tests/test.hs b/tests/test.hs
--- a/tests/test.hs
+++ b/tests/test.hs
@@ -3,6 +3,7 @@
 import Control.Monad
 import Control.Concurrent
 import Control.Concurrent.Async
+import Data.Maybe
 import System.Environment
 import System.Exit
 import System.Process
@@ -28,19 +29,23 @@
     _ -> do
       withFile "lock.log" WriteMode $ \h ->
         void $ mapConcurrently id
-          [ callSelf h ["shared", "300"]
-          , callSelf h ["shared", "200"]
-          , msleep 10 >> callSelf h ["exclusive", "500"]
-          , msleep 20 >> callSelf h ["try"]
-          , msleep 50 >> callSelf h ["shared", "500"]
-          , msleep 700 >> callSelf h ["shared", "10"]
-          , msleep 1500 >> callSelf h ["try"]
+          [ callSelf h ["shared", "5"]
+          , callSelf h ["shared", "2"]
+          , sleep 1 >> callSelf h ["exclusive", "3"]
+          , sleep 3 >> callSelf h ["try"]
+          , sleep 4 >> callSelf h ["shared", "1"]
+          , sleep 6 >> callSelf h ["shared", "1"]
+          , sleep 10 >> callSelf h ["try"]
           ]
-      msleep 2000
+      sleep 11
       log <- readFile "lock.log"
       expected <- readFile "tests/lock.log.expected"
       when (log /= expected) $ do
         putStrLn "log mismatch!"
+        putStrLn "log:"
+        putStrLn log
+        putStrLn "expected:"
+        putStrLn expected
         exitFailure
 
 callSelf :: Handle -> [String] -> IO ()
@@ -51,15 +56,15 @@
   ExitSuccess <- waitForProcess ph
   return ()
 
-msleep :: Int -> IO ()
-msleep = threadDelay . (*1000)
+sleep :: Int -> IO ()
+sleep = threadDelay . (*1000000)
 
 holdLock :: String -> SharedExclusive -> Int -> IO ()
 holdLock ty sex duration = do
   withFileLock lockfile sex $ \_ -> do
     putStrLn $ "took " ++ desc
-    msleep duration
-  putStrLn $ "released " ++ desc
+    sleep duration
+    putStrLn $ "releasing " ++ desc
   where
     desc = ty ++ " lock"
 
@@ -76,10 +81,9 @@
 tryHoldLock ty sex duration = do
   res <- withTryFileLock lockfile sex $ \_ -> do
     putStrLn $ "took " ++ desc
-    msleep duration
-  case res of
-    Nothing -> putStrLn "lock not available"
-    Just _  -> putStrLn $ "released " ++ desc
+    sleep duration
+    putStrLn $ "released " ++ desc
+  when (isNothing res) $ putStrLn "lock not available"
   where
     desc = ty ++ " lock"
 
