diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,7 @@
+0.3.1
+  * Add lockFd and withFdLock, locking with a user-provided file
+	descriptor. Thanks to Eelis for this feature.
+
 0.3
   * Protect against exception in withLock using monad-control. Thanks
     to Takahiro Himura for this feature.
diff --git a/System/Lock/FLock.hsc b/System/Lock/FLock.hsc
--- a/System/Lock/FLock.hsc
+++ b/System/Lock/FLock.hsc
@@ -1,21 +1,36 @@
-{-# LANGUAGE ForeignFunctionInterface, CPP, FlexibleContexts #-}
+{-# LANGUAGE ForeignFunctionInterface
+           , CPP
+           , FlexibleContexts
+           #-}
 module System.Lock.FLock
-      (withLock, lock, unlock,
-       SharedExclusive(Shared, Exclusive), Block(Block, NoBlock), Lock) where
+  ( withLock
+  , withFdLock
+  , lock
+  , lockFd
+  , unlock
+  , SharedExclusive(Shared, Exclusive)
+  , Block(Block, NoBlock)
+  , Lock
+  ) where
 
-import Control.Monad.IO.Class (MonadIO (..))
-import Data.Bits ((.|.))
+import Control.Exception.Lifted    ( bracket )
+import Control.Monad.IO.Class      ( MonadIO (..) )
+import Control.Monad.Trans.Control ( MonadBaseControl )
+import Data.Bits                   ( (.|.) )
+import Foreign.C.Error             ( throwErrnoIfMinus1_ )
 #if __GLASGOW_HASKELL__ > 702
-import Foreign.C.Types (CInt(..))
+import Foreign.C.Types             ( CInt(..) )
 #else
-import Foreign.C.Types (CInt)
+import Foreign.C.Types             ( CInt )
 #endif
-import System.Posix.Error (throwErrnoPathIfMinus1_)
-import System.Posix.IO (openFd, defaultFileFlags, closeFd,
-                        OpenMode(ReadOnly, WriteOnly))
-import System.Posix.Types (Fd(Fd))
-import Control.Monad.Trans.Control (MonadBaseControl)
-import Control.Exception.Lifted (bracket)
+import System.Posix.Error          ( throwErrnoPathIfMinus1_ )
+import System.Posix.IO             ( openFd
+                                   , defaultFileFlags
+                                   , closeFd
+                                   , OpenMode(ReadOnly, WriteOnly)
+                                   , dup
+                                   )
+import System.Posix.Types          ( Fd(Fd) )
 
 #include <sys/file.h>
 
@@ -40,19 +55,41 @@
     unlock
     (const x)
 
+withFdLock :: (MonadIO m, MonadBaseControl IO m) => Fd -> SharedExclusive -> Block -> m a -> m a
+withFdLock fd se b x =
+  bracket
+    (lockFd fd se b)
+    unlock
+    (const x)
+
+operation :: SharedExclusive -> Block -> CInt
+operation se b =
+  case b of
+    Block   -> op
+    NoBlock -> op .|. c_LOCK_NB
+  where
+    op = case se of
+           Shared    -> c_LOCK_SH
+           Exclusive -> c_LOCK_EX
+
 lock :: MonadIO m => FilePath -> SharedExclusive -> Block -> m Lock
-lock fp se b = liftIO
-             $ do Fd fd <- openFd fp om Nothing defaultFileFlags
-                  throwErrnoPathIfMinus1_ "flock" fp $ flock fd op'
-                  return (Lock fd)
-    where (om, op) = case se of
-                         Shared -> (ReadOnly, c_LOCK_SH)
-                         Exclusive -> (WriteOnly, c_LOCK_EX)
-          op' = case b of
-                    Block -> op
-                    NoBlock -> op .|. c_LOCK_NB
+lock fp se b = liftIO $
+  do Fd fd <- openFd fp om Nothing defaultFileFlags
+     throwErrnoPathIfMinus1_ "flock" fp $ flock fd (operation se b)
+     return (Lock fd)
+  where
+    om = case se of
+           Shared    -> ReadOnly
+           Exclusive -> WriteOnly
 
+lockFd :: MonadIO m => Fd -> SharedExclusive -> Block -> m Lock
+lockFd fd se b = liftIO $
+  do (Fd fd') <- dup fd
+     throwErrnoIfMinus1_ "flock" $ flock fd' (operation se b)
+     return (Lock fd')
+
 unlock :: MonadIO m => Lock -> m ()
-unlock (Lock fd) = liftIO $ do _ <- flock fd c_LOCK_UN
-                               closeFd (Fd fd)
+unlock (Lock fd) = liftIO $
+  do _ <- flock fd c_LOCK_UN
+     closeFd (Fd fd)
 
diff --git a/flock.cabal b/flock.cabal
--- a/flock.cabal
+++ b/flock.cabal
@@ -1,5 +1,5 @@
 Name:               flock
-Version:            0.3
+Version:            0.3.1
 License:            OtherLicense
 License-File:       COPYING
 Copyright:          Ian Lynagh, 2007
