about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2013-08-28 12:27:10 -0700
committerTim Chevalier <chevalier@alum.wellesley.edu>2013-08-30 15:48:37 -0700
commit34ed4e26a2c08edc50bb797170212daaad048e46 (patch)
tree6ee791b15ee0acd40c0b841d7571ad19dd6c7e86 /src
parent8464ee04a423808bf110640adf5c9c4952b1f9cf (diff)
downloadrust-34ed4e26a2c08edc50bb797170212daaad048e46.tar.gz
rust-34ed4e26a2c08edc50bb797170212daaad048e46.zip
std: Add a file-renaming function to std::os
Diffstat (limited to 'src')
-rw-r--r--src/libstd/os.rs12
-rw-r--r--src/test/run-pass/rename-directory.rs57
2 files changed, 69 insertions, 0 deletions
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 07e0b0857a1..91408162788 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 00000000000..60791688385
--- /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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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() }