1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

feat(unstable): add Deno.futime and Deno.futimeSync (#7266)

This commit is contained in:
Casper Beyer 2020-09-01 02:29:43 +08:00 committed by GitHub
parent c82c3b982e
commit 32de714dc7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 179 additions and 2 deletions

5
Cargo.lock generated
View file

@ -348,6 +348,7 @@ dependencies = [
"dlopen",
"dprint-plugin-typescript",
"encoding_rs",
"filetime",
"futures",
"fwdansi",
"http",
@ -564,9 +565,9 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
[[package]]
name = "filetime"
version = "0.2.10"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "affc17579b132fc2461adf7c575cc6e8b134ebca52c51f5411388965227dc695"
checksum = "3ed85775dcc68644b5c950ac06a2b23768d3bc9390464151aaf27136998dcf9e"
dependencies = [
"cfg-if",
"libc",

View file

@ -42,6 +42,7 @@ dlopen = "0.1.8"
encoding_rs = "0.8.23"
dprint-plugin-typescript = "0.30.2"
futures = "0.3.5"
filetime = "0.2.12"
http = "0.2.1"
idna = "0.2.0"
indexmap = "1.5.1"

View file

@ -1247,6 +1247,40 @@ declare namespace Deno {
export function createHttpClient(
options: CreateHttpClientOptions,
): HttpClient;
/** **UNSTABLE**: needs investigation into high precision time.
*
* Synchronously changes the access (`atime`) and modification (`mtime`) times
* of a file stream resource referenced by `rid`. Given times are either in
* seconds (UNIX epoch time) or as `Date` objects.
*
* ```ts
* const file = Deno.openSync("file.txt", { create: true });
* Deno.futimeSync(file.rid, 1556495550, new Date());
* ```
*/
export function futimeSync(
rid: number,
atime: number | Date,
mtime: number | Date,
): void;
/** **UNSTABLE**: needs investigation into high precision time.
*
* Changes the access (`atime`) and modification (`mtime`) times of a file
* stream resource referenced by `rid`. Given times are either in seconds
* (UNIX epoch time) or as `Date` objects.
*
* ```ts
* const file = await Deno.open("file.txt", { create: true });
* await Deno.futime(file.rid, 1556495550, new Date());
* ```
*/
export function futime(
rid: number,
atime: number | Date,
mtime: number | Date,
): Promise<void>;
}
declare function fetch(

View file

@ -174,6 +174,12 @@ pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
i.register_op("op_cwd", s.stateful_json_op_sync(t, op_cwd));
i.register_op("op_futime_sync", s.stateful_json_op_sync(t, op_futime_sync));
i.register_op(
"op_futime_async",
s.stateful_json_op_async(t, op_futime_async),
);
i.register_op("op_utime_sync", s.stateful_json_op_sync(t, op_utime_sync));
i.register_op(
"op_utime_async",
@ -1673,6 +1679,65 @@ async fn op_make_temp_file_async(
.unwrap()
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct FutimeArgs {
rid: i32,
atime: i64,
mtime: i64,
}
fn op_futime_sync(
state: &State,
resource_table: &mut ResourceTable,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
state.check_unstable("Deno.futimeSync");
let args: FutimeArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
let atime = filetime::FileTime::from_unix_time(args.atime, 0);
let mtime = filetime::FileTime::from_unix_time(args.mtime, 0);
std_file_resource(resource_table, rid, |r| match r {
Ok(std_file) => {
filetime::set_file_handle_times(std_file, Some(atime), Some(mtime))
.map_err(ErrBox::from)
}
Err(_) => Err(ErrBox::type_error(
"cannot futime on this type of resource".to_string(),
)),
})?;
Ok(json!({}))
}
async fn op_futime_async(
state: Rc<State>,
resource_table: Rc<RefCell<ResourceTable>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
state.check_unstable("Deno.futime");
let args: FutimeArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
let atime = filetime::FileTime::from_unix_time(args.atime, 0);
let mtime = filetime::FileTime::from_unix_time(args.mtime, 0);
let mut resource_table = resource_table.borrow_mut();
std_file_resource(&mut resource_table, rid, |r| match r {
Ok(std_file) => {
filetime::set_file_handle_times(std_file, Some(atime), Some(mtime))
.map_err(ErrBox::from)
}
Err(_) => Err(ErrBox::type_error(
"cannot futime on this type of resource".to_string(),
)),
})?;
Ok(json!({}))
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct UtimeArgs {

View file

@ -268,6 +268,32 @@
return v instanceof Date ? Math.trunc(v.valueOf() / 1000) : v;
}
function futimeSync(
rid,
atime,
mtime,
) {
sendSync("op_futime_sync", {
rid,
// TODO(caspervonb) split atime, mtime into [seconds, nanoseconds] tuple
atime: toSecondsFromEpoch(atime),
mtime: toSecondsFromEpoch(mtime),
});
}
async function futime(
rid,
atime,
mtime,
) {
await sendAsync("op_futime_async", {
rid,
// TODO(caspervonb) split atime, mtime into [seconds, nanoseconds] tuple
atime: toSecondsFromEpoch(atime),
mtime: toSecondsFromEpoch(mtime),
});
}
function utimeSync(
path,
atime,
@ -364,6 +390,8 @@
umask,
link,
linkSync,
futime,
futimeSync,
utime,
utimeSync,
symlink,

View file

@ -118,6 +118,8 @@ __bootstrap.denoNsUnstable = {
umask: __bootstrap.fs.umask,
link: __bootstrap.fs.link,
linkSync: __bootstrap.fs.linkSync,
futime: __bootstrap.fs.futime,
futimeSync: __bootstrap.fs.futimeSync,
utime: __bootstrap.fs.utime,
utimeSync: __bootstrap.fs.utimeSync,
symlink: __bootstrap.fs.symlink,

View file

@ -13,6 +13,50 @@ function assertFuzzyTimestampEquals(t1: Date | null, t2: Date): void {
assert(Math.abs(t1.valueOf() - t2.valueOf()) < 10_000);
}
unitTest(
{ perms: { read: true, write: true } },
async function futimeSyncSuccess(): Promise<void> {
const testDir = await Deno.makeTempDir();
const filename = testDir + "/file.txt";
const file = await Deno.open(filename, {
create: true,
write: true,
});
const atime = 1000;
const mtime = 50000;
await Deno.futime(file.rid, atime, mtime);
await Deno.fdatasync(file.rid);
const fileInfo = Deno.statSync(filename);
assertFuzzyTimestampEquals(fileInfo.atime, new Date(atime * 1000));
assertFuzzyTimestampEquals(fileInfo.mtime, new Date(mtime * 1000));
file.close();
},
);
unitTest(
{ perms: { read: true, write: true } },
function futimeSyncSuccess(): void {
const testDir = Deno.makeTempDirSync();
const filename = testDir + "/file.txt";
const file = Deno.openSync(filename, {
create: true,
write: true,
});
const atime = 1000;
const mtime = 50000;
Deno.futimeSync(file.rid, atime, mtime);
Deno.fdatasyncSync(file.rid);
const fileInfo = Deno.statSync(filename);
assertFuzzyTimestampEquals(fileInfo.atime, new Date(atime * 1000));
assertFuzzyTimestampEquals(fileInfo.mtime, new Date(mtime * 1000));
file.close();
},
);
unitTest(
{ perms: { read: true, write: true } },
function utimeSyncFileSuccess(): void {

View file

@ -86,6 +86,8 @@ delete Object.prototype.__proto__;
"fdatasync",
"fdatasyncSync",
"formatDiagnostics",
"futime",
"futimeSync",
"fstat",
"fstatSync",
"fsync",