summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--js/deno.ts2
-rw-r--r--js/os.ts25
-rw-r--r--js/unit_tests.ts30
-rw-r--r--src/fs.rs6
-rw-r--r--src/handlers.rs30
-rwxr-xr-xtools/test.py2
6 files changed, 89 insertions, 6 deletions
diff --git a/js/deno.ts b/js/deno.ts
index 060b2d526..ff9939b1b 100644
--- a/js/deno.ts
+++ b/js/deno.ts
@@ -1,4 +1,4 @@
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
// Public deno module.
-export { exit, readFileSync } from "./os";
+export { exit, readFileSync, writeFileSync } from "./os";
export { libdeno } from "./globals";
diff --git a/js/os.ts b/js/os.ts
index 22ef6ef4f..22bbd7748 100644
--- a/js/os.ts
+++ b/js/os.ts
@@ -121,15 +121,32 @@ export function readFileSync(filename: string): Uint8Array {
export function writeFileSync(
filename: string,
data: Uint8Array,
- perm: number
+ perm = 0o666
): void {
- util.notImplemented();
- /*
- pubInternal("os", {
+ /* Ideally we could write:
+ const res = send({
command: fbs.Command.WRITE_FILE_SYNC,
writeFileSyncFilename: filename,
writeFileSyncData: data,
writeFileSyncPerm: perm
});
*/
+ const builder = new flatbuffers.Builder();
+ const filename_ = builder.createString(filename);
+ const dataOffset = fbs.WriteFileSync.createDataVector(builder, data);
+ fbs.WriteFileSync.startWriteFileSync(builder);
+ fbs.WriteFileSync.addFilename(builder, filename_);
+ fbs.WriteFileSync.addData(builder, dataOffset);
+ fbs.WriteFileSync.addPerm(builder, perm);
+ const msg = fbs.WriteFileSync.endWriteFileSync(builder);
+ fbs.Base.startBase(builder);
+ fbs.Base.addMsg(builder, msg);
+ fbs.Base.addMsgType(builder, fbs.Any.WriteFileSync);
+ builder.finish(fbs.Base.endBase(builder));
+ const resBuf = libdeno.send(builder.asUint8Array());
+ if (resBuf != null) {
+ const bb = new flatbuffers.ByteBuffer(new Uint8Array(resBuf!));
+ const baseRes = fbs.Base.getRootAsBase(bb);
+ maybeThrowError(baseRes);
+ }
}
diff --git a/js/unit_tests.ts b/js/unit_tests.ts
index f203444fa..6eebf8860 100644
--- a/js/unit_tests.ts
+++ b/js/unit_tests.ts
@@ -5,6 +5,7 @@
import { test, assert, assertEqual } from "./testing/testing.ts";
import { readFileSync } from "deno";
+import * as deno from "deno";
import "./compiler_test.ts";
@@ -109,6 +110,35 @@ test(function tests_readFileSync_NotFound() {
});
*/
+/* TODO(ry) Add this once we can create a tmpDir to write the file into.
+test(function writeFileSyncSuccess() {
+ const enc = new TextEncoder();
+ const dataWritten = enc.encode("Hello");
+ const filename = "TEMPDIR/test.txt";
+ deno.writeFileSync(filename, dataWritten, 0o666);
+ const dataRead = readFileSync(filename);
+ assertEqual(dataRead, dataWritten);
+});
+*/
+
+// For this test to pass we need --allow-write permission.
+// Otherwise it will fail with deno.PermissionDenied instead of deno.NotFound.
+test(function writeFileSyncFail() {
+ const enc = new TextEncoder();
+ const data = enc.encode("Hello");
+ const filename = "/baddir/test.txt";
+ // The following should fail because /baddir doesn't exist (hopefully).
+ let caughtError = false;
+ try {
+ deno.writeFileSync(filename, data);
+ } catch (e) {
+ caughtError = true;
+ // TODO assertEqual(e, deno.NotFound);
+ assertEqual(e.name, "deno.NotFound");
+ }
+ assert(caughtError);
+});
+
test(async function tests_fetch() {
const response = await fetch("http://localhost:4545/package.json");
const json = await response.json();
diff --git a/src/fs.rs b/src/fs.rs
index 0aaf2a93d..9191d5373 100644
--- a/src/fs.rs
+++ b/src/fs.rs
@@ -1,6 +1,7 @@
use std;
use std::fs::File;
use std::io::Read;
+use std::io::Write;
use std::path::Path;
pub fn read_file_sync(path: &Path) -> std::io::Result<Vec<u8>> {
@@ -17,6 +18,11 @@ pub fn read_file_sync_string(path: &Path) -> std::io::Result<String> {
.map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))
}
+pub fn write_file_sync(path: &Path, content: &[u8]) -> std::io::Result<()> {
+ let mut f = File::create(path)?;
+ f.write_all(content)
+}
+
pub fn mkdir(path: &Path) -> std::io::Result<()> {
debug!("mkdir -p {}", path.display());
assert!(path.has_root(), "non-has_root not yet implemented");
diff --git a/src/handlers.rs b/src/handlers.rs
index 853fbbc77..1b8a59173 100644
--- a/src/handlers.rs
+++ b/src/handlers.rs
@@ -70,6 +70,14 @@ pub extern "C" fn msg_from_js(d: *const DenoC, buf: deno_buf) {
let filename = msg.filename().unwrap();
handle_read_file_sync(d, &mut builder, filename)
}
+ msg::Any::WriteFileSync => {
+ // TODO base.msg_as_WriteFileSync();
+ let msg = msg::WriteFileSync::init_from_table(base.msg().unwrap());
+ let filename = msg.filename().unwrap();
+ let data = msg.data().unwrap();
+ let perm = msg.perm();
+ handle_write_file_sync(d, &mut builder, filename, data, perm)
+ }
_ => panic!(format!(
"Unhandled message {}",
msg::enum_name_any(msg_type)
@@ -413,6 +421,28 @@ fn handle_read_file_sync(
))
}
+fn handle_write_file_sync(
+ d: *const DenoC,
+ builder: &mut FlatBufferBuilder,
+ filename: &str,
+ data: &[u8],
+ perm: u32,
+) -> HandlerResult {
+ debug!("handle_write_file_sync {}", filename);
+ let deno = from_c(d);
+ if deno.flags.allow_write {
+ // TODO(ry) Use perm.
+ fs::write_file_sync(Path::new(filename), data)?;
+ Ok(null_buf())
+ } else {
+ let err = std::io::Error::new(
+ std::io::ErrorKind::PermissionDenied,
+ "allow_write is off.",
+ );
+ Err(err.into())
+ }
+}
+
// TODO(ry) Use Deno instead of DenoC as first arg.
fn remove_timer(d: *const DenoC, timer_id: u32) {
let deno = from_c(d);
diff --git a/tools/test.py b/tools/test.py
index 75886874e..12582f83f 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -41,7 +41,7 @@ def main(argv):
deno_exe = os.path.join(build_dir, "deno" + executable_suffix)
check_exists(deno_exe)
- run([deno_exe, "js/unit_tests.ts"])
+ run([deno_exe, "js/unit_tests.ts", "--allow-write"])
check_exists(deno_exe)
check_output_test(deno_exe)