Skip to content

Commit

Permalink
Port fsync, waitpid and remove_file to core::{os,libc}.
Browse files Browse the repository at this point in the history
  • Loading branch information
graydon committed Mar 5, 2012
1 parent faccd4a commit 5bf185b
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 1 deletion.
20 changes: 20 additions & 0 deletions src/libcore/libc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down Expand Up @@ -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;
}
}
}

Expand Down
102 changes: 101 additions & 1 deletion src/libcore/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}


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

0 comments on commit 5bf185b

Please sign in to comment.