Skip to content

Commit 5bf185b

Browse files
committed
Port fsync, waitpid and remove_file to core::{os,libc}.
1 parent faccd4a commit 5bf185b

File tree

2 files changed

+121
-1
lines changed

2 files changed

+121
-1
lines changed

src/libcore/libc.rs

+20
Original file line numberDiff line numberDiff line change
@@ -1018,11 +1018,23 @@ mod funcs {
10181018
fn readlink(path: *c_char, buf: *mutable c_char,
10191019
bufsz: size_t) -> ssize_t;
10201020

1021+
fn fsync(fd: c_int) -> c_int;
1022+
1023+
#[cfg(target_os = "linux")]
1024+
fn fdatasync(fd: c_int) -> c_int;
1025+
10211026
fn setenv(name: *c_char, val: *c_char,
10221027
overwrite: c_int) -> c_int;
10231028
fn unsetenv(name: *c_char) -> c_int;
10241029
fn putenv(string: *c_char) -> c_int;
10251030
}
1031+
1032+
#[nolink]
1033+
#[abi = "cdecl"]
1034+
native mod wait {
1035+
fn waitpid(pid: pid_t, status: *mutable c_int,
1036+
options: c_int) -> pid_t;
1037+
}
10261038
}
10271039

10281040
#[cfg(target_os = "win32")]
@@ -1098,9 +1110,17 @@ mod funcs {
10981110
fn CreateDirectoryA(lpPathName: LPCSTR,
10991111
lpSecurityAttributes:
11001112
LPSECURITY_ATTRIBUTES) -> BOOL;
1113+
fn DeleteFileA(lpPathName: LPCSTR) -> BOOL;
11011114
fn RemoveDirectoryA(lpPathName: LPCSTR) -> BOOL;
11021115
fn SetCurrentDirectoryA(lpPathName: LPCSTR) -> BOOL;
11031116
}
1117+
1118+
#[abi = "cdecl"]
1119+
#[nolink]
1120+
native mod msvcrt {
1121+
#[link_name = "_commit"]
1122+
fn commit(fd: c_int) -> c_int;
1123+
}
11041124
}
11051125
}
11061126

src/libcore/os.rs

+101-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// facts of which OS the user is on -- they should be given the opportunity
1515
// to write OS-ignorant code by default.
1616

17-
import libc::{c_char, c_void, c_int, c_uint, size_t, mode_t, FILE};
17+
import libc::{c_char, c_void, c_int, c_uint, size_t, mode_t, pid_t, FILE};
1818
import libc::{close, fclose};
1919

2020
import getcwd = rustrt::rust_getcwd;
@@ -32,6 +32,7 @@ native mod rustrt {
3232
fn rust_path_is_dir(path: str::sbuf) -> c_int;
3333
fn rust_path_exists(path: str::sbuf) -> c_int;
3434
fn rust_list_files(path: str) -> [str];
35+
fn rust_process_wait(handle: c_int) -> c_int;
3536
}
3637

3738

@@ -96,6 +97,77 @@ fn fdopen(fd: c_int) -> *FILE {
9697
}
9798

9899

100+
// fsync related
101+
102+
enum fsync_level {
103+
// whatever fsync does on that platform
104+
fsync,
105+
106+
// fdatasync on linux, similiar or more on other platforms
107+
fdatasync,
108+
109+
// full fsync
110+
//
111+
// You must additionally sync the parent directory as well!
112+
fullfsync,
113+
}
114+
115+
#[cfg(target_os = "win32")]
116+
fn fsync_fd(fd: c_int, _level: fsync_level) -> c_int {
117+
import libc::funcs::extra::msvcrt::*;
118+
ret commit(fd);
119+
}
120+
121+
#[cfg(target_os = "linux")]
122+
fn fsync_fd(fd: c_int, level: fsync_level) -> c_int {
123+
import libc::funcs::posix01::unistd::*;
124+
alt level {
125+
fsync | fullfsync { ret fsync(fd); }
126+
fdatasync { ret fdatasync(fd); }
127+
}
128+
}
129+
130+
#[cfg(target_os = "macos")]
131+
fn fsync_fd(fd: c_int, level: fsync_level) -> c_int {
132+
import libc::consts::os::extra::*;
133+
import libc::funcs::posix88::fcntl::*;
134+
import libc::funcs::posix01::unistd::*;
135+
alt level {
136+
fsync { ret fsync(fd); }
137+
_ {
138+
// According to man fnctl, the ok retval is only specified to be !=-1
139+
if (fcntl(F_FULLFSYNC as c_int, fd) == -1 as c_int)
140+
{ ret -1 as c_int; }
141+
else
142+
{ ret 0 as c_int; }
143+
}
144+
}
145+
}
146+
147+
#[cfg(target_os = "freebsd")]
148+
fn fsync_fd(fd: c_int, _l: fsync_level) -> c_int {
149+
import libc::funcs::posix01::unistd::*;
150+
ret fsync(fd);
151+
}
152+
153+
154+
#[cfg(target_os = "win32")]
155+
fn waitpid(pid: pid_t) -> c_int {
156+
ret rustrt::rust_process_wait(pid);
157+
}
158+
159+
#[cfg(target_os = "linux")]
160+
#[cfg(target_os = "freebsd")]
161+
#[cfg(target_os = "macos")]
162+
fn waitpid(pid: pid_t) -> c_int {
163+
import libc::funcs::posix01::wait::*;
164+
let status = 0 as c_int;
165+
166+
assert (waitpid(pid, ptr::mut_addr_of(status),
167+
0 as c_int) != (-1 as c_int));
168+
ret status;
169+
}
170+
99171

100172
#[cfg(target_os = "linux")]
101173
#[cfg(target_os = "freebsd")]
@@ -406,6 +478,34 @@ fn change_dir(p: path) -> bool {
406478
}
407479
}
408480

481+
/*
482+
Function: remove_file
483+
484+
Deletes an existing file.
485+
*/
486+
fn remove_file(p: path) -> bool {
487+
ret unlink(p);
488+
489+
#[cfg(target_os = "win32")]
490+
fn unlink(p: path) -> bool {
491+
// FIXME: remove imports when export globs work properly.
492+
import libc::funcs::extra::kernel32;
493+
import libc::types::os::arch::extra::*;
494+
ret as_c_charp(p) {|buf|
495+
kernel32::DeleteFileA(buf) != (0 as BOOL)
496+
};
497+
}
498+
499+
#[cfg(target_os = "linux")]
500+
#[cfg(target_os = "macos")]
501+
#[cfg(target_os = "freebsd")]
502+
fn unlink(p: path) -> bool {
503+
ret as_c_charp(p) {|buf|
504+
libc::unlink(buf) == (0 as c_int)
505+
};
506+
}
507+
}
508+
409509

410510

411511
#[cfg(target_os = "macos")]

0 commit comments

Comments
 (0)