Port fsync, waitpid and remove_file to core::{os,libc}.

This commit is contained in:
Graydon Hoare 2012-03-05 13:20:57 -08:00
parent faccd4ac92
commit 5bf185b499
2 changed files with 121 additions and 1 deletions

View file

@ -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;
}
}
}

View file

@ -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")]