diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+
+Copyright (c) 2009 Robin Green
+
+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 Robin Green 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/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,8 @@
+#!/usr/bin/env runhaskell
+> import Distribution.Simple
+> import System.Process (rawSystem)
+> import System.Exit (ExitCode(..))
+> main = defaultMainWithHooks $ simpleUserHooks { runTests = \args _ _ _ -> do
+>     ExitSuccess <- rawSystem "runhaskell" ("Test.hs" : args)
+>     return ()
+> }
diff --git a/System/IO/Cautious.hs b/System/IO/Cautious.hs
new file mode 100644
--- /dev/null
+++ b/System/IO/Cautious.hs
@@ -0,0 +1,57 @@
+{-# LANGUAGE CPP #-}
+-- | It is recommended to write
+--
+-- import Prelude hiding (writeFile)
+--
+-- when importing this module.
+module System.IO.Cautious
+  ( writeFile
+  , writeFileWithBackup
+  ) where
+
+import Prelude hiding (writeFile)
+
+import System.Directory (renameFile)
+import System.FilePath (splitFileName)
+import System.IO (openTempFile)
+#ifdef _POSIX
+import Control.Monad (when)
+import Data.Function (fix)
+import Data.List (genericDrop)
+import System.Posix.IO (closeFd, FdOption (SynchronousWrites), fdWrite, handleToFd, setFdOption)
+import System.Posix.Types (Fd)
+
+-- | Don't bother to split into two writes if the string to write is shorter than this
+splitLimit :: Int
+splitLimit = 65536
+
+-- | Write the entire contents of a string to a file descriptor. Assumes blocking mode.
+writeAll :: Fd -> String -> IO ()
+writeAll fd = fix $ \me s -> when (not $ null s) $ do
+    count <- fdWrite fd s
+    me $ genericDrop count s
+#else
+import System.IO (hPutStr, hClose)
+#endif
+
+writeFile :: FilePath -> String -> IO ()
+writeFile = writeFileWithBackup $ return ()
+
+-- | Backs up the old version of the file with "backup". "backup" must not fail if there is no
+-- old version of the file.
+writeFileWithBackup :: IO () -> FilePath -> String -> IO ()
+writeFileWithBackup backup fp text = do
+    (tempFP, handle) <- uncurry openTempFile $ splitFileName fp
+#ifdef _POSIX
+    fd <- handleToFd handle
+    let writeSync = (setFdOption fd SynchronousWrites True >>) . writeAll fd
+    if null $ drop splitLimit text
+      then writeSync text
+      else writeAll fd (init text) >> writeSync [last text]
+    closeFd fd
+#else
+    hPutStr handle text
+    hClose handle
+#endif
+    backup
+    renameFile tempFP fp
diff --git a/cautious-file.cabal b/cautious-file.cabal
new file mode 100644
--- /dev/null
+++ b/cautious-file.cabal
@@ -0,0 +1,31 @@
+name:                cautious-file
+version:             0.1.1
+Cabal-Version:	     >= 1.6
+synopsis:            Ways to write a file cautiously, to reduce the chances of problems such as data loss due to crashes or power failures
+description:         If the posix flag is enabled, posix-specific functions are used to reduce the chance of data loss further
+category:            System
+license:             BSD3
+license-file:        LICENSE
+copyright:	     Copyright (C) Robin Green 2009
+author:              Robin Green
+maintainer:          Robin Green <greenrd@greenrd.org>
+build-type:	     Custom
+stability:	     experimental
+bug-reports:	     mailto:greenrd@greenrd.org
+tested-with:	     GHC == 6.10.3
+
+source-repository head
+  type:     darcs
+  location: http://patch-tag.com/publicrepos/cautious-file
+
+Flag posix
+    description: Use POSIX-specific features
+    default: True
+
+Library
+  build-Depends:	base >= 4, base < 5, directory, filepath
+  if flag(posix)
+    cpp-options: -D_POSIX
+    build-Depends: unix
+  exposed-modules:      System.IO.Cautious
+  ghc-options:          -Wall
