Skip to content

Commit f9abd99

Browse files
committed
Add bindings to uv's utime function
This exposes the ability to change the modification and access times on a file. Closes #10266
1 parent 497d63f commit f9abd99

File tree

6 files changed

+67
-5
lines changed

6 files changed

+67
-5
lines changed

src/librustuv/file.rs

+10
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,16 @@ impl FsRequest {
237237
})
238238
}
239239

240+
pub fn utime(loop_: &Loop, path: &CString, atime: u64, mtime: u64)
241+
-> Result<(), UvError>
242+
{
243+
execute_nop(|req, cb| unsafe {
244+
uvll::uv_fs_utime(loop_.handle, req, path.with_ref(|p| p),
245+
atime as libc::c_double, mtime as libc::c_double,
246+
cb)
247+
})
248+
}
249+
240250
pub fn get_result(&self) -> c_int {
241251
unsafe { uvll::get_result_from_fs_req(self.req) }
242252
}

src/librustuv/uvio.rs

+6
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,12 @@ impl IoFactory for UvIoFactory {
313313
let r = FsRequest::readlink(self.uv_loop(), path);
314314
r.map_err(uv_error_to_io_error)
315315
}
316+
fn fs_utime(&mut self, path: &CString, atime: u64, mtime: u64)
317+
-> Result<(), IoError>
318+
{
319+
let r = FsRequest::utime(self.uv_loop(), path, atime, mtime);
320+
r.map_err(uv_error_to_io_error)
321+
}
316322

317323
fn spawn(&mut self, config: ProcessConfig)
318324
-> Result<(~RtioProcess, ~[Option<~RtioPipe>]), IoError>

src/librustuv/uvll.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
#[allow(non_camel_case_types)]; // C types
3131

32-
use std::libc::{size_t, c_int, c_uint, c_void, c_char, uintptr_t};
32+
use std::libc::{size_t, c_int, c_uint, c_void, c_char, uintptr_t, c_double};
3333
use std::libc::ssize_t;
3434
use std::libc::{malloc, free};
3535
use std::libc;
@@ -824,6 +824,9 @@ externfn!(fn uv_fs_symlink(handle: *uv_loop_t, req: *uv_fs_t, src: *c_char,
824824
dst: *c_char, flags: c_int, cb: uv_fs_cb) -> c_int)
825825
externfn!(fn uv_fs_rename(handle: *uv_loop_t, req: *uv_fs_t, src: *c_char,
826826
dst: *c_char, cb: uv_fs_cb) -> c_int)
827+
externfn!(fn uv_fs_utime(handle: *uv_loop_t, req: *uv_fs_t, path: *c_char,
828+
atime: c_double, mtime: c_double,
829+
cb: uv_fs_cb) -> c_int)
827830
externfn!(fn uv_fs_link(handle: *uv_loop_t, req: *uv_fs_t, src: *c_char,
828831
dst: *c_char, cb: uv_fs_cb) -> c_int)
829832
externfn!(fn uv_fs_chown(handle: *uv_loop_t, req: *uv_fs_t, src: *c_char,

src/libstd/rt/io/fs.rs

+42-2
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,21 @@ pub fn rmdir_recursive(path: &Path) {
587587
rmdir(path);
588588
}
589589

590+
/// Changes the timestamps for a file's last modification and access time.
591+
/// The file at the path specified will have its last access time set to
592+
/// `atime` and its modification time set to `mtime`.
593+
///
594+
/// # Errors
595+
///
596+
/// This function will raise on the `io_error` condition if an error
597+
/// happens.
598+
// FIXME(#10301) these arguments should not be u64
599+
pub fn change_file_times(path: &Path, atime: u64, mtime: u64) {
600+
do io_raise |io| {
601+
io.fs_utime(&path.to_c_str(), atime, mtime)
602+
};
603+
}
604+
590605
impl Reader for File {
591606
fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
592607
match self.fd.read(buf) {
@@ -704,8 +719,8 @@ mod test {
704719
use rt::io;
705720
use str;
706721
use super::{File, rmdir, mkdir, readdir, rmdir_recursive, mkdir_recursive,
707-
copy, unlink, stat, symlink, link, readlink, chmod, chown,
708-
lstat};
722+
copy, unlink, stat, symlink, link, readlink, chmod,
723+
lstat, change_file_times};
709724

710725
fn tmpdir() -> Path {
711726
use os;
@@ -1244,4 +1259,29 @@ mod test {
12441259

12451260
rmdir_recursive(&tmpdir);
12461261
}
1262+
1263+
#[test]
1264+
fn utime() {
1265+
let tmpdir = tmpdir();
1266+
let path = tmpdir.join("a");
1267+
File::create(&path);
1268+
1269+
change_file_times(&path, 100, 200);
1270+
assert_eq!(path.stat().accessed, 100);
1271+
assert_eq!(path.stat().modified, 200);
1272+
1273+
rmdir_recursive(&tmpdir);
1274+
}
1275+
1276+
#[test]
1277+
fn utime_noexist() {
1278+
let tmpdir = tmpdir();
1279+
1280+
match io::result(|| change_file_times(&tmpdir.join("a"), 100, 200)) {
1281+
Ok(*) => fail!(),
1282+
Err(*) => {}
1283+
}
1284+
1285+
rmdir_recursive(&tmpdir);
1286+
}
12471287
}

src/libstd/rt/io/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1142,8 +1142,9 @@ pub struct FileStat {
11421142
/// The file permissions currently on the file
11431143
perm: FilePermission,
11441144

1145-
// XXX: These time fields are pretty useless without an actual time
1146-
// representation, what are the milliseconds relative to?
1145+
// FIXME(#10301): These time fields are pretty useless without an actual
1146+
// time representation, what are the milliseconds relative
1147+
// to?
11471148

11481149
/// The time that the file was created at, in platform-dependent
11491150
/// milliseconds

src/libstd/rt/rtio.rs

+2
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ pub trait IoFactory {
125125
fn fs_readlink(&mut self, path: &CString) -> Result<Path, IoError>;
126126
fn fs_symlink(&mut self, src: &CString, dst: &CString) -> Result<(), IoError>;
127127
fn fs_link(&mut self, src: &CString, dst: &CString) -> Result<(), IoError>;
128+
fn fs_utime(&mut self, src: &CString, atime: u64, mtime: u64) ->
129+
Result<(), IoError>;
128130

129131
// misc
130132
fn timer_init(&mut self) -> Result<~RtioTimer, IoError>;

0 commit comments

Comments
 (0)