   end
 
   @doc """
-  Copies the contents in `source` to `destination`.
-  Similar to the command `cp -r` in Unix systems,
-  this function behaves differently depending
-  if `source` and `destination` are a file or a directory.
-
-  If both are files, it simply copies `source` to
-  `destination`. However, if `destination` is a directory,
-  it copies the contents of `source` to `destination/source`
-  recursively.
-
-  If a file already exists in the destination,
-  it invokes a callback which should return
-  true if the existing file should be overriden,
-  false otherwise. It defaults to return true.
+  Copies the contents in `source` to `destination` preserving its mode.
+
+  Similar to the command `cp` in Unix systems, this function
+  behaves differently depending if `destination` is a directory
+  or not. In paritcular, if `destination` is a directory, it
+  copies the contents of `source` to `destination/source`.
+
+  If a file already exists in the destination, it invokes a
+  callback which should return true if the existing file
+  should be overriden, false otherwise. It defaults to return true.
 
   It returns `:ok` in case of success, returns
   `{ :error, reason }` otherwise.
+
+  If you want to copy contents from an io device to another device
+  or do a straight copy from a source to a destination without
+  preserving modes, check `File.copy/3` instead.
   """
   def cp(source, destination, callback // fn(_, _) -> true end) do
-    if dir?(source) do
-      { :error, :eisdir }
-    else
-      output =
-        if dir?(destination) do
-          mkdir(destination)
-          FN.join(destination, FN.basename(source))
-        else
-          destination
-        end
-
-      case do_cp_file(source, output, callback, []) do
-        { :error, reason, _ } -> { :error, reason }
-        _ -> :ok
+    output =
+      if dir?(destination) do
+        mkdir(destination)
+        FN.join(destination, FN.basename(source))
+      else
+        destination
       end
+
+    case do_cp_file(source, output, callback, []) do
+      { :error, reason, _ } -> { :error, reason }
+      _ -> :ok
     end
   end
 

  end

  @doc """
  Copies the contents of `source` to `destination`. Both
  parameters can be a filename or an io device opened with `File.open`.
  `bytes_count` specifies the number of bytes to count, the default
  being `:infinity`.

  If file `destination` already exists, it is overriden
  by the contents in `source`.

      File.read!("invalid.txt")
      #=> raises File.Error

  In general, a developer should use the former in case he wants
  to react in the fie does not exist. The latter should be used
  when the developer expects his software to fail in case the
  file cannot be read (i.e. it is literally an exception).
  """

  alias :file,     as: F
