about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2012-03-05 13:20:57 -0800
committerGraydon Hoare <graydon@mozilla.com>2012-03-05 14:00:44 -0800
commit5bf185b4995975a98bdf1855a0da01bb29ec202d (patch)
tree3e5a7a770fc54ca6da8ef997cff0e130d3b082d1
parentfaccd4ac92cd5785c89f646eeccb042f35161066 (diff)
downloadrust-5bf185b4995975a98bdf1855a0da01bb29ec202d.tar.gz
rust-5bf185b4995975a98bdf1855a0da01bb29ec202d.zip
Port fsync, waitpid and remove_file to core::{os,libc}.
-rw-r--r--src/libcore/libc.rs20
-rw-r--r--src/libcore/os.rs102
2 files changed, 121 insertions, 1 deletions
diff --git a/src/libcore/libc.rs b/src/libcore/libc.rs
index 0c16a378c25..fceb1f9f086 100644
--- a/src/libcore/libc.rs
+++ b/src/libcore/libc.rs
@@ -1018,11 +1018,23 @@ mod funcs {
             fn readlink(path: *c_char, buf: *mutable c_char,
                         bufsz: size_t) -> ssize_t;
 
+            fn fsync(fd: c_int) -> c_int;
+
+            #[cfg(target_os = "linux")]
+            fn fdatasync(fd: c_int) -> c_int;
+
             fn setenv(name: *c_char, val: *c_char,
                       overwrite: c_int) -> c_int;
             fn unsetenv(name: *c_char) -> c_int;
             fn putenv(string: *c_char) -> c_int;
         }
+
+        #[nolink]
+        #[abi = "cdecl"]
+        native mod wait {
+            fn waitpid(pid: pid_t, status: *mutable c_int,
+                       options: c_int) -> pid_t;
+        }
     }
 
     #[cfg(target_os = "win32")]
@@ -1098,9 +1110,17 @@ mod funcs {
             fn CreateDirectoryA(lpPathName: LPCSTR,
                                 lpSecurityAttributes:
                                 LPSECURITY_ATTRIBUTES) -> BOOL;
+            fn DeleteFileA(lpPathName: LPCSTR) -> BOOL;
             fn RemoveDirectoryA(lpPathName: LPCSTR) -> BOOL;
             fn SetCurrentDirectoryA(lpPathName: LPCSTR) -> BOOL;
         }
+
+        #[abi = "cdecl"]
+        #[nolink]
+        native mod msvcrt {
+            #[link_name = "_commit"]
+            fn commit(fd: c_int) -> c_int;
+        }
     }
 }
 
diff --git a/src/libcore/os.rs b/src/libcore/os.rs
index 9c40d8b99f3..c57b4420b67 100644
--- a/src/libcore/os.rs
+++ b/src/libcore/os.rs
@@ -14,7 +14,7 @@
 // facts of which OS the user is on -- they should be given the opportunity
 // to write OS-ignorant code by default.
 
-import libc::{c_char, c_void, c_int, c_uint, size_t, mode_t, FILE};
+import libc::{c_char, c_void, c_int, c_uint, size_t, mode_t, pid_t, FILE};
 import libc::{close, fclose};
 
 import getcwd = rustrt::rust_getcwd;
@@ -32,6 +32,7 @@ native mod rustrt {
     fn rust_path_is_dir(path: str::sbuf) -> c_int;
     fn rust_path_exists(path: str::sbuf) -> c_int;
     fn rust_list_files(path: str) -> [str];
+    fn rust_process_wait(handle: c_int) -> c_int;
 }
 
 
@@ -96,6 +97,77 @@ fn fdopen(fd: c_int) -> *FILE {
 }
 
 
+// fsync related
+
+enum fsync_level {
+    // whatever fsync does on that platform
+    fsync,
+
+    // fdatasync on linux, similiar or more on other platforms
+    fdatasync,
+
+    // full fsync
+    //
+    // You must additionally sync the parent directory as well!
+    fullfsync,
+}
+
+#[cfg(target_os = "win32")]
+fn fsync_fd(fd: c_int, _level: fsync_level) -> c_int {
+    import libc::funcs::extra::msvcrt::*;
+    ret commit(fd);
+}
+
+#[cfg(target_os = "linux")]
+fn fsync_fd(fd: c_int, level: fsync_level) -> c_int {
+    import libc::funcs::posix01::unistd::*;
+    alt level {
+      fsync | fullfsync { ret fsync(fd); }
+      fdatasync { ret fdatasync(fd); }
+    }
+}
+
+#[cfg(target_os = "macos")]
+fn fsync_fd(fd: c_int, level: fsync_level) -> c_int {
+    import libc::consts::os::extra::*;
+    import libc::funcs::posix88::fcntl::*;
+    import libc::funcs::posix01::unistd::*;
+    alt level {
+      fsync { ret fsync(fd); }
+      _ {
+        // According to man fnctl, the ok retval is only specified to be !=-1
+        if (fcntl(F_FULLFSYNC as c_int, fd) == -1 as c_int)
+            { ret -1 as c_int; }
+        else
+            { ret 0 as c_int; }
+      }
+    }
+}
+
+#[cfg(target_os = "freebsd")]
+fn fsync_fd(fd: c_int, _l: fsync_level) -> c_int {
+    import libc::funcs::posix01::unistd::*;
+    ret fsync(fd);
+}
+
+
+#[cfg(target_os = "win32")]
+fn waitpid(pid: pid_t) -> c_int {
+    ret rustrt::rust_process_wait(pid);
+}
+
+#[cfg(target_os = "linux")]
+#[cfg(target_os = "freebsd")]
+#[cfg(target_os = "macos")]
+fn waitpid(pid: pid_t) -> c_int {
+    import libc::funcs::posix01::wait::*;
+    let status = 0 as c_int;
+
+    assert (waitpid(pid, ptr::mut_addr_of(status),
+                    0 as c_int) != (-1 as c_int));
+    ret status;
+}
+
 
 #[cfg(target_os = "linux")]
 #[cfg(target_os = "freebsd")]
@@ -406,6 +478,34 @@ fn change_dir(p: path) -> bool {
     }
 }
 
+/*
+Function: remove_file
+
+Deletes an existing file.
+*/
+fn remove_file(p: path) -> bool {
+    ret unlink(p);
+
+    #[cfg(target_os = "win32")]
+    fn unlink(p: path) -> bool {
+        // FIXME: remove imports when export globs work properly.
+        import libc::funcs::extra::kernel32;
+        import libc::types::os::arch::extra::*;
+        ret as_c_charp(p) {|buf|
+            kernel32::DeleteFileA(buf) != (0 as BOOL)
+        };
+    }
+
+    #[cfg(target_os = "linux")]
+    #[cfg(target_os = "macos")]
+    #[cfg(target_os = "freebsd")]
+    fn unlink(p: path) -> bool {
+        ret as_c_charp(p) {|buf|
+            libc::unlink(buf) == (0 as c_int)
+        };
+    }
+}
+
 
 
 #[cfg(target_os = "macos")]