Skip to content

Commit

Permalink
Modifications to os::copy_file()
Browse files Browse the repository at this point in the history
* Returns `false` if destination exists.
* Returns `false` if source is not a file (e.g. dir, sym link, etc.).

cc #9947
  • Loading branch information
hatahet committed Oct 30, 2013
1 parent cd1661d commit e783959
Showing 1 changed file with 40 additions and 9 deletions.
49 changes: 40 additions & 9 deletions src/libstd/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ pub fn self_exe_path() -> Option<Path> {
* 'USERPROFILE' environment variable if it is set and not equal to the empty
* string.
*
* Otherwise, homedir returns option::none.
* Otherwise, homedir returns `None`.
*/
pub fn homedir() -> Option<Path> {
// FIXME (#7188): getenv needs a ~[u8] variant
Expand Down Expand Up @@ -627,7 +627,7 @@ pub fn path_exists(p: &Path) -> bool {
}

/**
* Convert a relative path to an absolute path
* Converts a relative path to an absolute path
*
* If the given path is relative, return it prepended with the current working
* directory. If the given path is already an absolute path, return it
Expand Down Expand Up @@ -676,7 +676,7 @@ pub fn make_dir(p: &Path, mode: c_int) -> bool {
}

/// Creates a directory with a given mode.
/// Returns true iff creation
/// Returns `true` iff creation
/// succeeded. Also creates all intermediate subdirectories
/// if they don't already exist, giving all of them the same mode.
Expand Down Expand Up @@ -788,11 +788,9 @@ pub fn list_dir(p: &Path) -> ~[Path] {
}
}

/**
* Lists the contents of a directory
*
* This version prepends each entry with the directory.
*/
/// Lists the contents of a directory
///
/// This version prepends each entry with the directory.
pub fn list_dir_path(p: &Path) -> ~[Path] {
list_dir(p).map(|f| p.join(f))
}
Expand Down Expand Up @@ -873,8 +871,26 @@ pub fn change_dir(p: &Path) -> bool {
}
}

/// Copies a file from one location to another
/**
* Copies a file from one location to another
*
* Returns `false` if the destination path exists, or if the source path is not
* a file.
*
* Note: this does not protect against concurrent systems which may create the
* destination before the file is copied, but after is it checked not to exist.
*/
pub fn copy_file(from: &Path, to: &Path) -> bool {
if to.exists() {
return false;
}

// Only proceed if `from` is a file
match from.stat() {
Some(st) => if !st.is_file { return false; },
None => ()
}

return do_copy_file(from, to);

#[cfg(windows)]
Expand Down Expand Up @@ -2007,6 +2023,21 @@ mod tests {
}
}

#[test]
fn copy_file_destination_exists() {
let tempdir = getcwd();
let input = tempdir.join("in.txt");
let out = tempdir.join("in.txt"); // Same as above.
assert!(!os::copy_file(&input, &out));
}

#[test]
fn copy_file_source_is_dir() {
let tempdir = getcwd();
let out = tempdir.join("out.txt");
assert!(!os::copy_file(&tempdir, &out));
}

#[test]
fn recursive_mkdir_slash() {
let path = Path::new("/");
Expand Down

4 comments on commit e783959

@bors
Copy link
Contributor

@bors bors commented on e783959 Oct 30, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from alexcrichton
at hatahet@e783959

@bors
Copy link
Contributor

@bors bors commented on e783959 Oct 30, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging hatahet/rust/master = e783959 into auto

@bors
Copy link
Contributor

@bors bors commented on e783959 Oct 30, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hatahet/rust/master = e783959 merged ok, testing candidate = 59e5aae9

@bors
Copy link
Contributor

@bors bors commented on e783959 Oct 30, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.