summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock5
-rw-r--r--cli/Cargo.toml1
-rw-r--r--cli/dts/lib.deno.unstable.d.ts34
-rw-r--r--cli/ops/fs.rs65
-rw-r--r--cli/rt/30_fs.js28
-rw-r--r--cli/rt/90_deno_ns.js2
-rw-r--r--cli/tests/unit/utime_test.ts44
-rw-r--r--cli/tsc/99_main_compiler.js2
8 files changed, 179 insertions, 2 deletions
diff --git a/Cargo.lock b/Cargo.lock
index fe1743063..c0fa63f14 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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",
diff --git a/cli/Cargo.toml b/cli/Cargo.toml
index e0f75da15..7c8414e55 100644
--- a/cli/Cargo.toml
+++ b/cli/Cargo.toml
@@ -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"
diff --git a/cli/dts/lib.deno.unstable.d.ts b/cli/dts/lib.deno.unstable.d.ts
index 14079f300..9c5590f97 100644
--- a/cli/dts/lib.deno.unstable.d.ts
+++ b/cli/dts/lib.deno.unstable.d.ts
@@ -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(
diff --git a/cli/ops/fs.rs b/cli/ops/fs.rs
index 3b8946057..794518e2c 100644
--- a/cli/ops/fs.rs
+++ b/cli/ops/fs.rs
@@ -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",
@@ -1675,6 +1681,65 @@ async fn op_make_temp_file_async(
#[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 {
path: String,
atime: i64,
diff --git a/cli/rt/30_fs.js b/cli/rt/30_fs.js
index d8171bdac..750c3c1ba 100644
--- a/cli/rt/30_fs.js
+++ b/cli/rt/30_fs.js
@@ -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,
diff --git a/cli/rt/90_deno_ns.js b/cli/rt/90_deno_ns.js
index ac22410f6..82acdef3c 100644
--- a/cli/rt/90_deno_ns.js
+++ b/cli/rt/90_deno_ns.js
@@ -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,
diff --git a/cli/tests/unit/utime_test.ts b/cli/tests/unit/utime_test.ts
index cc68e90cd..185187ef4 100644
--- a/cli/tests/unit/utime_test.ts
+++ b/cli/tests/unit/utime_test.ts
@@ -15,6 +15,50 @@ function assertFuzzyTimestampEquals(t1: Date | null, t2: Date): void {
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 {
const testDir = Deno.makeTempDirSync();
const filename = testDir + "/file.txt";
diff --git a/cli/tsc/99_main_compiler.js b/cli/tsc/99_main_compiler.js
index 79af46e31..aa334907a 100644
--- a/cli/tsc/99_main_compiler.js
+++ b/cli/tsc/99_main_compiler.js
@@ -86,6 +86,8 @@ delete Object.prototype.__proto__;
"fdatasync",
"fdatasyncSync",
"formatDiagnostics",
+ "futime",
+ "futimeSync",
"fstat",
"fstatSync",
"fsync",