From 34ed4e26a2c08edc50bb797170212daaad048e46 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Wed, 28 Aug 2013 12:27:10 -0700 Subject: [PATCH] std: Add a file-renaming function to std::os --- src/libstd/os.rs | 12 ++++++ src/test/run-pass/rename-directory.rs | 57 +++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 src/test/run-pass/rename-directory.rs diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 07e0b0857a18..914081627880 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -1002,6 +1002,18 @@ pub fn remove_file(p: &Path) -> bool { } } +/// Renames an existing file or directory +pub fn rename_file(old: &Path, new: &Path) -> bool { + #[fixed_stack_segment]; #[inline(never)]; + unsafe { + do old.with_c_str |old_buf| { + do new.with_c_str |new_buf| { + libc::rename(old_buf, new_buf) == (0 as c_int) + } + } + } +} + #[cfg(unix)] /// Returns the platform-specific value of errno pub fn errno() -> int { diff --git a/src/test/run-pass/rename-directory.rs b/src/test/run-pass/rename-directory.rs new file mode 100644 index 000000000000..607916883858 --- /dev/null +++ b/src/test/run-pass/rename-directory.rs @@ -0,0 +1,57 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// This test can't be a unit test in std, +// because it needs mkdtemp, which is in extra + +// xfail-fast +extern mod extra; + +use extra::tempfile::mkdtemp; +use std::os; +use std::libc; +use std::libc::*; + +fn rename_directory() { + #[fixed_stack_segment]; + unsafe { + static U_RWX: i32 = (S_IRUSR | S_IWUSR | S_IXUSR) as i32; + + let tmpdir = mkdtemp(&os::tmpdir(), "rename_directory").expect("rename_directory failed"); + let old_path = tmpdir.push_many(["foo", "bar", "baz"]); + assert!(os::mkdir_recursive(&old_path, U_RWX)); + let test_file = &old_path.push("temp.txt"); + + /* Write the temp input file */ + let ostream = do test_file.to_str().with_c_str |fromp| { + do "w+b".with_c_str |modebuf| { + libc::fopen(fromp, modebuf) + } + }; + assert!((ostream as uint != 0u)); + let s = ~"hello"; + do "hello".with_c_str |buf| { + let write_len = libc::fwrite(buf as *c_void, + 1u as size_t, + (s.len() + 1u) as size_t, + ostream); + assert_eq!(write_len, (s.len() + 1) as size_t) + } + assert_eq!(libc::fclose(ostream), (0u as c_int)); + + let new_path = tmpdir.push_many(["quux", "blat"]); + assert!(os::mkdir_recursive(&new_path, U_RWX)); + assert!(os::rename_file(&old_path, &new_path.push("newdir"))); + assert!(os::path_is_dir(&new_path.push("newdir"))); + assert!(os::path_exists(&new_path.push_many(["newdir", "temp.txt"]))); + } +} + +fn main() { rename_directory() }