diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c)2010, Antoine Latter
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Antoine Latter nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/MonadCatchIO-transformers-foreign.cabal b/MonadCatchIO-transformers-foreign.cabal
new file mode 100644
--- /dev/null
+++ b/MonadCatchIO-transformers-foreign.cabal
@@ -0,0 +1,29 @@
+-- MonadCatchIO-mtl-foreign.cabal auto-generated by cabal init. For
+-- additional options, see
+-- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr.
+Name:                MonadCatchIO-transformers-foreign
+Version:             0.1
+Synopsis:            Polymorphic combinators for working with foreign functions
+Description:         Functions like 'alloca' are provided, except not restricted
+                     to 'IO'.
+License:             BSD3
+License-file:        LICENSE
+Author:              Antoine Latter
+Maintainer:          aslatter@gmail.com
+-- Copyright:           
+Category:            Control
+Build-type:          Simple
+-- Extra-source-files:  
+Cabal-version:       >=1.6
+
+Library
+  Exposed-modules:     Control.Monad.CatchIO.Foreign
+  Build-depends:       base == 4.*, MonadCatchIO-transformers == 0.2.*,
+                       transformers == 0.2.*
+
+  if impl(ghc)
+    Build-depends:     primitive == 0.3.*
+
+  Hs-Source-Dirs:      src/
+  -- Other-modules:       
+  -- Build-tools:         
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/src/Control/Monad/CatchIO/Foreign.hs b/src/Control/Monad/CatchIO/Foreign.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/CatchIO/Foreign.hs
@@ -0,0 +1,78 @@
+{-# LANGUAGE CPP, MagicHash, UnboxedTuples #-}
+{-|
+  This module assumes that you are familiar with the funcitons
+  of the same name in Foreign.Marshall.Alloc, Foreign.Marshal.AllocArray
+  and in Foreign.ForeignPtr.
+
+  The functions are generalized to work in any monad which is an
+  instance of MonadCatchIO.
+ -}
+module Control.Monad.CatchIO.Foreign
+    ( alloca
+    , allocaBytes
+    , allocaArray
+    , allocaArray0
+    , withForeignPtr
+    )
+    where
+
+-- this is a bit dodgy - we use the MIN_VERSION macro to
+-- see if we're compiled against transformers or mtl
+#ifdef MIN_VERSION_transformers
+import Control.Monad.IO.Class(liftIO)
+#else
+import Control.Monad.Trans (liftIO)
+#endif
+
+import Control.Monad.CatchIO
+
+import qualified Foreign as F
+import Foreign (Ptr,ForeignPtr, sizeOf, alignment, Storable)
+
+#ifdef __GLASGOW_HASKELL__
+import qualified Data.Primitive as P
+import GHC.Exts
+import GHC.IOBase hiding (liftIO)
+#endif
+
+alloca :: (F.Storable a, MonadCatchIO m) => (Ptr a -> m b) -> m b
+alloca  = doAlloca undefined
+  where
+    doAlloca       :: (MonadCatchIO m', Storable a') => a' -> (Ptr a' -> m' b') -> m' b'
+    doAlloca dummy  = allocaBytesAligned (F.sizeOf dummy) (F.alignment dummy)
+
+allocaBytes :: (MonadCatchIO m) => Int -> (Ptr a -> m b) -> m b
+allocaBytes size = bracket (liftIO $ F.mallocBytes size) (liftIO . F.free)
+
+allocaBytesAligned :: (MonadCatchIO m) => Int -> Int -> (Ptr a -> m b) -> m b
+#ifdef __GLASGOW_HASKELL__
+allocaBytesAligned size alignment k
+ = do
+  ba <- liftIO $ P.newAlignedPinnedByteArray size alignment >>= P.unsafeFreezeByteArray
+  r <- k $ case P.byteArrayContents ba of
+             P.Addr addr# -> Ptr addr#
+  liftIO $ touch ba
+  return r
+
+touch :: a -> IO ()
+touch a = IO $ \s -> case touch# a s of
+                       s' -> (# s', () #)
+
+#else
+allocaBytesAligned size _ = allocaBytes size -- wrong, but the FFI doesn't offer anything else
+#endif
+
+allocaArray :: (F.Storable a, MonadCatchIO m) => Int -> (Ptr a -> m b) -> m b
+allocaArray  = doAlloca undefined
+  where
+    doAlloca            :: (Storable a', MonadCatchIO m') => a' -> Int -> (Ptr a' -> m' b') -> m' b'
+    doAlloca dummy size  = allocaBytesAligned (size * sizeOf dummy) (alignment dummy)
+
+allocaArray0 :: (F.Storable a, MonadCatchIO m) => Int -> (Ptr a -> m b) -> m b
+allocaArray0 size = allocaArray (size + 1)
+
+withForeignPtr :: (MonadCatchIO m) => ForeignPtr a -> (Ptr a -> m b) -> m b
+withForeignPtr fo io
+    = do r <- io (F.unsafeForeignPtrToPtr fo)
+         liftIO $ F.touchForeignPtr fo
+         return r
