diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,31 @@
+Copyright (c) 2011, Henning Thielemann
+
+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.
+
+    * The names of contributors may not 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/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,3 @@
+#! /usr/bin/env runhaskell
+> import Distribution.Simple
+> main = defaultMain
diff --git a/poll.cabal b/poll.cabal
new file mode 100644
--- /dev/null
+++ b/poll.cabal
@@ -0,0 +1,33 @@
+Name:             poll
+Version:          0.0
+License:          BSD3
+License-File:     LICENSE
+Author:           Henning Thielemann <haskell@henning-thielemann.de>, Dylan Simon <dylan@dylex.net>
+Maintainer:       Henning Thielemann <haskell@henning-thielemann.de>
+Category:         System
+Build-Type:       Simple
+Synopsis:         Bindings to poll.h
+Description:
+  Poll functionality allows to wait on different FileDescriptors simultaneously.
+Tested-With:      GHC==6.12.3
+Cabal-Version:    >=1.6
+Build-Type:       Simple
+Source-Repository head
+  type:     darcs
+  location: http://code.haskell.org/~thielema/poll/
+
+Source-Repository this
+  type:     darcs
+  location: http://code.haskell.org/~thielema/poll/
+  tag:      0.0
+
+Library
+  Build-Depends:
+    enumset >=0.0.2 && <0.1,
+    utility-ht >=0.0.7 && <0.1,
+    base >=3 && <5
+
+  GHC-Options:      -Wall
+  Hs-Source-Dirs:   src
+  Exposed-Modules:
+    System.Posix.Poll
diff --git a/src/System/Posix/Poll.hsc b/src/System/Posix/Poll.hsc
new file mode 100644
--- /dev/null
+++ b/src/System/Posix/Poll.hsc
@@ -0,0 +1,112 @@
+module System.Posix.Poll (
+  Fd(..),
+  Event(..),
+  Events,
+  inp, pri, out, err, hup, nVal,
+  ) where
+
+#include <poll.h>
+
+import Foreign.C.Types (CShort, )
+import Foreign.Storable
+          (Storable(sizeOf, alignment, peek, poke),
+           peekByteOff, pokeByteOff, )
+import qualified System.Posix.Types as Posix
+import Data.Ix (Ix, range, index, inRange, rangeSize, )
+import Data.Maybe (fromMaybe, )
+import qualified Data.Ix.Enum as IxEnum
+import qualified Data.EnumSet as EnumSet
+
+data Event 
+  = Other Int
+  | In
+  | Pri
+  | Out
+  | Err
+  | Hup
+  | NVal
+  deriving (Eq, Ord, Show)
+
+eventFlagSet :: Event -> Events
+eventFlagSet cap =
+   case cap of
+      Other n -> EnumSet.singletonByPosition n
+      In      -> inp
+      Pri     -> pri
+      Out     -> out
+      Err     -> err
+      Hup     -> hup
+      NVal    -> nVal
+
+{- |
+The Enum instance may not be very efficient,
+but it should hardly be used, at all.
+Better use constants such as 'inp' and set manipulation.
+If the binary logarithm is computed by constant unfolding,
+performance would be better, but direct set manipulation is still faster.
+We implement the 'Enum' instance in this way,
+in order to stay independent from the particular Poll definitions,
+that may differ between platforms.
+-}
+instance Enum Event where
+   fromEnum cap =
+      case cap of
+         Other n -> n
+         _ -> EnumSet.mostSignificantPosition (eventFlagSet cap)
+   toEnum n =
+      fromMaybe (Other n) $
+      lookup (EnumSet.singletonByPosition n) $
+      map (\ev -> (eventFlagSet ev, ev)) $
+         In :
+         Pri :
+         Out :
+         Err :
+         Hup :
+         NVal :
+         []
+
+instance Ix Event where
+   range     = IxEnum.range
+   index     = IxEnum.index
+   inRange   = IxEnum.inRange
+   rangeSize = IxEnum.rangeSize
+
+{-
+pollMask :: PollEvent -> CShort
+pollMask PollIn	  = #{const POLLIN}
+pollMask PollPri  = #{const POLLPRI}
+pollMask PollOut  = #{const POLLOUT}
+pollMask PollErr  = #{const POLLERR}
+pollMask PollHup  = #{const POLLHUP}
+pollMask PollNVal = #{const POLLNVAL}
+-}
+
+inp, pri, out, err, hup, nVal :: Events
+inp  = EnumSet.Cons #{const POLLIN}
+pri  = EnumSet.Cons #{const POLLPRI}
+out  = EnumSet.Cons #{const POLLOUT}
+err  = EnumSet.Cons #{const POLLERR}
+hup  = EnumSet.Cons #{const POLLHUP}
+nVal = EnumSet.Cons #{const POLLNVAL}
+
+
+type Events = EnumSet.T CShort Event
+
+data Fd = Fd
+  { fd :: Posix.Fd
+  , events :: Events
+  , rEvents :: Events
+  }
+
+instance Storable Fd where
+  sizeOf _    = #size struct pollfd
+  alignment _ = 4
+  peek p      = do
+    f <- #{peek struct pollfd, fd}      p
+    e <- #{peek struct pollfd, events}  p
+    r <- #{peek struct pollfd, revents} p
+    return $ Fd (Posix.Fd f) e r
+  poke p (Fd (Posix.Fd f) e r) = do
+    #{poke struct pollfd, fd}      p f
+    #{poke struct pollfd, events}  p e
+    #{poke struct pollfd, revents} p r
