diff --git a/System/Directory.hs b/System/Directory.hs
--- a/System/Directory.hs
+++ b/System/Directory.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE CPP #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
 {-# LANGUAGE PackageImports #-}
 
 -- |
@@ -21,6 +22,7 @@
 	, fileSize
 	, rename
 	, modified
+	, canonicalizePath
 	, listDirectory
 	
 	-- * Creating things
@@ -49,6 +51,8 @@
 
 import qualified Control.Exception as Exc
 import qualified Data.Text as T
+import           Foreign.Ptr (nullPtr)
+import           Foreign.C (CString, withCString, peekCString)
 import qualified System.Environment as SE
 import           System.FilePath (FilePath, append)
 import           System.FilePath.CurrentOS (currentOS)
@@ -69,6 +73,7 @@
 import           Data.Time (UTCTime)
 import           Data.Time.Clock.POSIX (posixSecondsToUTCTime)
 import qualified System.Posix as Posix
+import qualified System.Posix.Error as Posix
 
 #endif
 
@@ -142,6 +147,33 @@
 	Win32.moveFileEx old' new' Win32.mOVEFILE_REPLACE_EXISTING
 #else
 	Posix.rename old' new'
+#endif
+
+-- Resolve symlinks and \"..\" path elements to return a canonical path.
+-- It is intended that two paths referring to the same object will always
+-- resolve to the same canonical path.
+--
+-- Note that on many operating systems, it is impossible to guarantee that
+-- two paths to the same file will resolve to the same canonical path.
+--
+-- See: 'SD.canonicalizePath'
+--
+-- Since: 0.1.1
+canonicalizePath :: FilePath -> IO FilePath
+canonicalizePath path =
+	let path' = encode path in
+#ifdef CABAL_OS_WINDOWS
+	fmap decode (Win32.getFullPathName path')
+#else
+	withCString path' $ \cPath -> do
+		cOut <- Posix.throwErrnoPathIfNull "canonicalizePath" path' (c_realpath cPath nullPtr)
+		out <- peekCString cOut
+		return (decode out)
+#endif
+
+#ifndef CABAL_OS_WINDOWS
+foreign import ccall unsafe "realpath"
+	c_realpath :: CString -> CString -> IO CString
 #endif
 
 -- | Create a directory at a given path. The user may choose whether it is
diff --git a/System/File.hs b/System/File.hs
--- a/System/File.hs
+++ b/System/File.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE PackageImports #-}
+
 -- |
 -- Module: System.File
 -- Copyright: 2011 John Millikin
@@ -10,9 +12,12 @@
 -- computations. See the linked documentation for each computation for
 -- details on exceptions and operating system interaction.
 module System.File
-	( Handle
-	, Mode
+	( IO.Handle
+	, IO.IOMode(..)
 	
+	-- * File operations
+	, copyFile
+	
 	-- * Binary files
 	, openFile
 	, withFile
@@ -37,11 +42,18 @@
 import           System.FilePath (FilePath)
 import           System.FileIO.Internal (encode)
 
--- | Re&#x2010;exported for convenience.
-type Handle = IO.Handle
+import qualified "directory" System.Directory as SD
 
--- | Re&#x2010;exported for convenience.
-type Mode = IO.IOMode
+-- | Copy a file to a new entry in the filesystem. If a file already exists
+-- at the new location, it will be replaced.
+--
+-- See: 'SD.copyFile'
+--
+-- Since: 0.1.1
+copyFile :: FilePath -- ^ Old location
+         -> FilePath -- ^ New location
+         -> IO ()
+copyFile old new = SD.copyFile (encode old) (encode new)
 
 -- | Open a file in binary mode, and return an open 'Handle'. The 'Handle'
 -- should be 'IO.hClose'd when it is no longer needed.
@@ -50,7 +62,7 @@
 -- lifetime automatically.
 --
 -- See: 'IO.openBinaryFile'
-openFile :: FilePath -> Mode -> IO IO.Handle
+openFile :: FilePath -> IO.IOMode -> IO IO.Handle
 openFile path = IO.openBinaryFile (encode path)
 
 -- | Open a file in binary mode, and pass its 'Handle' to a provided
@@ -58,7 +70,7 @@
 -- computation returns.
 --
 -- See: 'IO.withBinaryFile'
-withFile :: FilePath -> Mode -> (IO.Handle -> IO a) -> IO a
+withFile :: FilePath -> IO.IOMode -> (IO.Handle -> IO a) -> IO a
 withFile path = IO.withBinaryFile (encode path)
 
 -- | Read in the entire contents of a binary file.
@@ -88,7 +100,7 @@
 -- 'Handle'&#x2019;s lifetime automatically.
 --
 -- See: 'IO.openFile'
-openTextFile :: FilePath -> Mode -> IO IO.Handle
+openTextFile :: FilePath -> IO.IOMode -> IO IO.Handle
 openTextFile path = IO.openFile (encode path)
 
 -- | Open a file in text mode, and pass its 'Handle' to a provided
@@ -96,7 +108,7 @@
 -- computation returns.
 --
 -- See: 'IO.withFile'
-withTextFile :: FilePath -> Mode -> (IO.Handle -> IO a) -> IO a
+withTextFile :: FilePath -> IO.IOMode -> (IO.Handle -> IO a) -> IO a
 withTextFile path = IO.withFile (encode path)
 
 -- | Read in the entire contents of a text file.
diff --git a/system-fileio.cabal b/system-fileio.cabal
--- a/system-fileio.cabal
+++ b/system-fileio.cabal
@@ -1,5 +1,5 @@
 name: system-fileio
-version: 0.1
+version: 0.1.1
 synopsis: High-level filesystem interaction
 license: MIT
 license-file: license.txt
