2019-01-01 19:58:40 -05:00
|
|
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
2019-02-02 22:05:30 -05:00
|
|
|
|
2019-02-08 22:13:04 -05:00
|
|
|
use atty;
|
|
|
|
use crate::ansi;
|
2019-01-14 01:30:38 -05:00
|
|
|
use crate::errors;
|
2019-03-01 19:25:50 -05:00
|
|
|
use crate::errors::{permission_denied, DenoError, DenoResult, ErrorKind};
|
2019-01-14 01:30:38 -05:00
|
|
|
use crate::fs as deno_fs;
|
|
|
|
use crate::http_util;
|
|
|
|
use crate::isolate::Buf;
|
|
|
|
use crate::isolate::Isolate;
|
|
|
|
use crate::isolate::IsolateState;
|
|
|
|
use crate::isolate::Op;
|
2019-02-28 16:19:04 -05:00
|
|
|
use crate::js_errors::apply_source_map;
|
|
|
|
use crate::js_errors::JSErrorColor;
|
2019-01-14 01:30:38 -05:00
|
|
|
use crate::libdeno;
|
|
|
|
use crate::msg;
|
|
|
|
use crate::msg_util;
|
|
|
|
use crate::repl;
|
|
|
|
use crate::resolve_addr::resolve_addr;
|
|
|
|
use crate::resources;
|
|
|
|
use crate::resources::table_entries;
|
|
|
|
use crate::resources::Resource;
|
|
|
|
use crate::tokio_util;
|
|
|
|
use crate::version;
|
2019-02-28 16:19:04 -05:00
|
|
|
use deno_core::JSError;
|
2018-09-18 14:53:16 -04:00
|
|
|
use flatbuffers::FlatBufferBuilder;
|
2018-08-09 15:17:08 -04:00
|
|
|
use futures;
|
2019-01-08 14:44:06 -05:00
|
|
|
use futures::Async;
|
2018-09-22 04:42:07 -04:00
|
|
|
use futures::Poll;
|
2019-01-08 14:44:06 -05:00
|
|
|
use futures::Sink;
|
|
|
|
use futures::Stream;
|
2018-08-15 20:57:36 -04:00
|
|
|
use hyper;
|
2018-10-26 12:14:06 -04:00
|
|
|
use hyper::rt::Future;
|
2018-09-10 23:40:03 -04:00
|
|
|
use remove_dir_all::remove_dir_all;
|
2018-08-13 19:55:10 -04:00
|
|
|
use std;
|
2018-11-29 22:03:00 -05:00
|
|
|
use std::convert::From;
|
2018-08-26 05:51:25 -04:00
|
|
|
use std::fs;
|
2019-01-13 22:14:59 -05:00
|
|
|
use std::net::Shutdown;
|
2018-08-09 13:24:30 -04:00
|
|
|
use std::path::Path;
|
2018-09-22 04:42:07 -04:00
|
|
|
use std::path::PathBuf;
|
2018-11-15 23:07:40 -05:00
|
|
|
use std::process::Command;
|
2019-03-01 19:25:50 -05:00
|
|
|
use std::sync::atomic::Ordering;
|
2019-01-08 14:44:06 -05:00
|
|
|
use std::sync::Arc;
|
2019-02-02 01:27:42 -05:00
|
|
|
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
|
2018-09-27 00:56:39 -04:00
|
|
|
use tokio;
|
2018-10-03 23:58:29 -04:00
|
|
|
use tokio::net::TcpListener;
|
|
|
|
use tokio::net::TcpStream;
|
2018-11-15 23:07:40 -05:00
|
|
|
use tokio_process::CommandExt;
|
2018-09-22 04:42:07 -04:00
|
|
|
use tokio_threadpool;
|
2018-08-15 23:36:48 -04:00
|
|
|
|
2019-02-08 22:13:04 -05:00
|
|
|
#[cfg(unix)]
|
|
|
|
use std::os::unix::fs::PermissionsExt;
|
|
|
|
#[cfg(unix)]
|
|
|
|
use std::os::unix::process::ExitStatusExt;
|
|
|
|
|
2018-09-05 22:13:36 -04:00
|
|
|
type OpResult = DenoResult<Buf>;
|
|
|
|
|
|
|
|
// TODO Ideally we wouldn't have to box the Op being returned.
|
|
|
|
// The box is just to make it easier to get a prototype refactor working.
|
2018-10-03 20:48:02 -04:00
|
|
|
type OpCreator =
|
2019-03-01 19:25:50 -05:00
|
|
|
fn(isolate: &Isolate, base: &msg::Base<'_>, data: libdeno::deno_buf)
|
2018-09-27 17:33:10 -04:00
|
|
|
-> Box<Op>;
|
2018-07-06 11:27:36 -04:00
|
|
|
|
2018-12-04 23:36:10 -05:00
|
|
|
#[inline]
|
2018-09-18 14:53:16 -04:00
|
|
|
fn empty_buf() -> Buf {
|
|
|
|
Box::new([])
|
|
|
|
}
|
|
|
|
|
2018-10-03 20:51:20 -04:00
|
|
|
/// Processes raw messages from JavaScript.
|
|
|
|
/// This functions invoked every time libdeno.send() is called.
|
|
|
|
/// control corresponds to the first argument of libdeno.send().
|
|
|
|
/// data corresponds to the second argument of libdeno.send().
|
|
|
|
pub fn dispatch(
|
2018-12-04 23:36:10 -05:00
|
|
|
isolate: &Isolate,
|
2018-12-04 16:21:02 -05:00
|
|
|
control: libdeno::deno_buf,
|
|
|
|
data: libdeno::deno_buf,
|
2018-09-27 17:33:10 -04:00
|
|
|
) -> (bool, Box<Op>) {
|
2018-12-04 16:21:02 -05:00
|
|
|
let base = msg::get_root_as_base(&control);
|
2018-09-18 14:53:16 -04:00
|
|
|
let is_sync = base.sync();
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner_type = base.inner_type();
|
2018-09-05 22:13:36 -04:00
|
|
|
let cmd_id = base.cmd_id();
|
2018-10-02 20:47:40 -04:00
|
|
|
|
2019-03-10 15:37:05 -04:00
|
|
|
let op: Box<Op> = {
|
2018-10-02 20:47:40 -04:00
|
|
|
// Handle regular ops.
|
2018-10-03 21:12:23 -04:00
|
|
|
let op_creator: OpCreator = match inner_type {
|
2018-10-17 20:41:21 -04:00
|
|
|
msg::Any::Accept => op_accept,
|
|
|
|
msg::Any::Chdir => op_chdir,
|
2018-10-26 16:01:45 -04:00
|
|
|
msg::Any::Chmod => op_chmod,
|
2018-10-17 20:41:21 -04:00
|
|
|
msg::Any::Close => op_close,
|
|
|
|
msg::Any::CopyFile => op_copy_file,
|
|
|
|
msg::Any::Cwd => op_cwd,
|
|
|
|
msg::Any::Dial => op_dial,
|
2018-10-03 20:48:02 -04:00
|
|
|
msg::Any::Environ => op_env,
|
2018-10-17 20:41:21 -04:00
|
|
|
msg::Any::Exit => op_exit,
|
2018-10-30 15:02:18 -04:00
|
|
|
msg::Any::Fetch => op_fetch,
|
2019-03-11 23:25:18 -04:00
|
|
|
msg::Any::FetchModuleMetaData => op_fetch_module_meta_data,
|
2019-02-09 16:55:40 -05:00
|
|
|
msg::Any::FormatError => op_format_error,
|
2019-03-10 15:37:05 -04:00
|
|
|
msg::Any::GlobalTimer => op_global_timer,
|
|
|
|
msg::Any::GlobalTimerStop => op_global_timer_stop,
|
2019-03-11 23:25:18 -04:00
|
|
|
msg::Any::IsTTY => op_is_tty,
|
2018-10-17 20:41:21 -04:00
|
|
|
msg::Any::Listen => op_listen,
|
2018-10-03 20:48:02 -04:00
|
|
|
msg::Any::MakeTempDir => op_make_temp_dir,
|
2018-10-17 20:41:21 -04:00
|
|
|
msg::Any::Metrics => op_metrics,
|
2018-10-03 20:48:02 -04:00
|
|
|
msg::Any::Mkdir => op_mkdir,
|
2019-03-11 23:25:18 -04:00
|
|
|
msg::Any::Now => op_now,
|
2018-10-03 20:48:02 -04:00
|
|
|
msg::Any::Open => op_open,
|
2019-03-11 23:25:18 -04:00
|
|
|
msg::Any::PermissionRevoke => op_revoke_permission,
|
|
|
|
msg::Any::Permissions => op_permissions,
|
|
|
|
msg::Any::Read => op_read,
|
2018-10-17 20:41:21 -04:00
|
|
|
msg::Any::ReadDir => op_read_dir,
|
|
|
|
msg::Any::ReadFile => op_read_file,
|
|
|
|
msg::Any::Readlink => op_read_link,
|
2018-10-03 20:48:02 -04:00
|
|
|
msg::Any::Remove => op_remove,
|
|
|
|
msg::Any::Rename => op_rename,
|
2018-11-05 12:55:59 -05:00
|
|
|
msg::Any::ReplReadline => op_repl_readline,
|
|
|
|
msg::Any::ReplStart => op_repl_start,
|
2018-10-30 15:58:55 -04:00
|
|
|
msg::Any::Resources => op_resources,
|
2018-11-15 23:07:40 -05:00
|
|
|
msg::Any::Run => op_run,
|
|
|
|
msg::Any::RunStatus => op_run_status,
|
2019-03-11 23:25:18 -04:00
|
|
|
msg::Any::Seek => op_seek,
|
2018-10-03 20:48:02 -04:00
|
|
|
msg::Any::SetEnv => op_set_env,
|
2018-10-17 20:41:21 -04:00
|
|
|
msg::Any::Shutdown => op_shutdown,
|
|
|
|
msg::Any::Start => op_start,
|
2018-10-03 20:48:02 -04:00
|
|
|
msg::Any::Stat => op_stat,
|
2018-10-17 20:41:21 -04:00
|
|
|
msg::Any::Symlink => op_symlink,
|
2018-10-03 20:48:02 -04:00
|
|
|
msg::Any::Truncate => op_truncate,
|
2019-01-08 14:44:06 -05:00
|
|
|
msg::Any::WorkerGetMessage => op_worker_get_message,
|
|
|
|
msg::Any::WorkerPostMessage => op_worker_post_message,
|
2018-10-17 20:41:21 -04:00
|
|
|
msg::Any::Write => op_write,
|
2019-01-08 14:44:06 -05:00
|
|
|
msg::Any::WriteFile => op_write_file,
|
2018-10-02 20:47:40 -04:00
|
|
|
_ => panic!(format!(
|
|
|
|
"Unhandled message {}",
|
2018-10-03 21:12:23 -04:00
|
|
|
msg::enum_name_any(inner_type)
|
2018-10-02 20:47:40 -04:00
|
|
|
)),
|
|
|
|
};
|
2019-03-01 19:25:50 -05:00
|
|
|
op_creator(&isolate, &base, data)
|
2018-08-15 23:36:48 -04:00
|
|
|
};
|
|
|
|
|
2018-10-15 16:46:42 -04:00
|
|
|
let boxed_op = Box::new(
|
|
|
|
op.or_else(move |err: DenoError| -> DenoResult<Buf> {
|
2018-09-18 14:53:16 -04:00
|
|
|
debug!("op err {}", err);
|
|
|
|
// No matter whether we got an Err or Ok, we want a serialized message to
|
|
|
|
// send back. So transform the DenoError into a deno_buf.
|
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
let errmsg_offset = builder.create_string(&format!("{}", err));
|
|
|
|
Ok(serialize_response(
|
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
|
|
|
error: Some(errmsg_offset),
|
|
|
|
error_kind: err.kind(),
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}).and_then(move |buf: Buf| -> DenoResult<Buf> {
|
|
|
|
// Handle empty responses. For sync responses we just want
|
|
|
|
// to send null. For async we want to send a small message
|
|
|
|
// with the cmd_id.
|
|
|
|
let buf = if is_sync || buf.len() > 0 {
|
|
|
|
buf
|
|
|
|
} else {
|
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
serialize_response(
|
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
)
|
2018-09-05 22:13:36 -04:00
|
|
|
};
|
2018-09-18 14:53:16 -04:00
|
|
|
Ok(buf)
|
2018-10-15 16:46:42 -04:00
|
|
|
}),
|
|
|
|
);
|
2018-08-15 23:36:48 -04:00
|
|
|
|
2018-09-18 14:53:16 -04:00
|
|
|
debug!(
|
|
|
|
"msg_from_js {} sync {}",
|
2018-10-03 21:12:23 -04:00
|
|
|
msg::enum_name_any(inner_type),
|
2018-09-18 14:53:16 -04:00
|
|
|
base.sync()
|
|
|
|
);
|
2018-11-04 09:04:24 -05:00
|
|
|
(base.sync(), boxed_op)
|
2018-07-13 03:24:07 -04:00
|
|
|
}
|
|
|
|
|
2019-02-02 01:27:42 -05:00
|
|
|
fn op_now(
|
2019-03-01 19:25:50 -05:00
|
|
|
_isolate: &Isolate,
|
2019-02-02 01:27:42 -05:00
|
|
|
base: &msg::Base<'_>,
|
|
|
|
data: libdeno::deno_buf,
|
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
|
|
|
let start = SystemTime::now();
|
|
|
|
let since_the_epoch = start.duration_since(UNIX_EPOCH).unwrap();
|
2019-02-08 11:14:33 -05:00
|
|
|
let time = since_the_epoch.as_secs() * 1000
|
|
|
|
+ u64::from(since_the_epoch.subsec_millis());
|
2019-02-02 01:27:42 -05:00
|
|
|
|
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
2019-02-08 11:14:33 -05:00
|
|
|
let inner = msg::NowRes::create(builder, &msg::NowResArgs { time });
|
2019-02-02 01:27:42 -05:00
|
|
|
ok_future(serialize_response(
|
|
|
|
base.cmd_id(),
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::NowRes,
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
2019-02-02 22:05:30 -05:00
|
|
|
fn op_is_tty(
|
2019-03-01 19:25:50 -05:00
|
|
|
_isolate: &Isolate,
|
2019-02-02 22:05:30 -05:00
|
|
|
base: &msg::Base<'_>,
|
|
|
|
_data: libdeno::deno_buf,
|
|
|
|
) -> Box<Op> {
|
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
let inner = msg::IsTTYRes::create(
|
|
|
|
builder,
|
|
|
|
&msg::IsTTYResArgs {
|
|
|
|
stdin: atty::is(atty::Stream::Stdin),
|
|
|
|
stdout: atty::is(atty::Stream::Stdout),
|
|
|
|
stderr: atty::is(atty::Stream::Stderr),
|
|
|
|
},
|
|
|
|
);
|
|
|
|
ok_future(serialize_response(
|
|
|
|
base.cmd_id(),
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::IsTTYRes,
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_exit(
|
2019-03-01 19:25:50 -05:00
|
|
|
_isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
_data: libdeno::deno_buf,
|
2018-09-27 17:33:10 -04:00
|
|
|
) -> Box<Op> {
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = base.inner_as_exit().unwrap();
|
|
|
|
std::process::exit(inner.code())
|
2018-09-02 02:33:24 -04:00
|
|
|
}
|
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_start(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-09-27 17:33:10 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
2018-09-05 22:13:36 -04:00
|
|
|
let mut builder = FlatBufferBuilder::new();
|
2018-08-13 19:55:10 -04:00
|
|
|
|
2019-03-01 19:25:50 -05:00
|
|
|
let argv = isolate
|
|
|
|
.state
|
|
|
|
.argv
|
|
|
|
.iter()
|
|
|
|
.map(|s| s.as_str())
|
|
|
|
.collect::<Vec<_>>();
|
2018-08-13 19:55:10 -04:00
|
|
|
let argv_off = builder.create_vector_of_strings(argv.as_slice());
|
|
|
|
|
|
|
|
let cwd_path = std::env::current_dir().unwrap();
|
2018-08-23 03:58:59 -04:00
|
|
|
let cwd_off =
|
2018-08-26 05:51:25 -04:00
|
|
|
builder.create_string(deno_fs::normalize_path(cwd_path.as_ref()).as_ref());
|
2018-08-13 19:55:10 -04:00
|
|
|
|
2019-02-15 11:22:02 -05:00
|
|
|
let exec_path =
|
|
|
|
builder.create_string(std::env::current_exe().unwrap().to_str().unwrap());
|
|
|
|
|
2018-11-05 01:21:21 -05:00
|
|
|
let v8_version = version::v8();
|
2018-10-15 20:52:33 -04:00
|
|
|
let v8_version_off = builder.create_string(v8_version);
|
|
|
|
|
2018-11-05 01:21:21 -05:00
|
|
|
let deno_version = version::DENO;
|
2018-10-15 20:52:33 -04:00
|
|
|
let deno_version_off = builder.create_string(deno_version);
|
|
|
|
|
2019-03-01 19:25:50 -05:00
|
|
|
let main_module = isolate
|
|
|
|
.state
|
|
|
|
.main_module()
|
|
|
|
.map(|m| builder.create_string(&m));
|
2019-02-12 21:14:02 -05:00
|
|
|
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = msg::StartRes::create(
|
2018-09-05 22:13:36 -04:00
|
|
|
&mut builder,
|
2018-08-13 19:55:10 -04:00
|
|
|
&msg::StartResArgs {
|
|
|
|
cwd: Some(cwd_off),
|
2019-01-06 14:16:42 -05:00
|
|
|
pid: std::process::id(),
|
2018-08-13 19:55:10 -04:00
|
|
|
argv: Some(argv_off),
|
2019-02-12 21:14:02 -05:00
|
|
|
main_module,
|
2019-03-01 19:25:50 -05:00
|
|
|
debug_flag: isolate.state.flags.log_debug,
|
|
|
|
types_flag: isolate.state.flags.types,
|
|
|
|
version_flag: isolate.state.flags.version,
|
2018-10-15 20:52:33 -04:00
|
|
|
v8_version: Some(v8_version_off),
|
|
|
|
deno_version: Some(deno_version_off),
|
2019-02-08 22:13:04 -05:00
|
|
|
no_color: !ansi::use_color(),
|
2019-02-15 11:22:02 -05:00
|
|
|
exec_path: Some(exec_path),
|
2018-08-13 19:55:10 -04:00
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
2018-09-09 19:48:10 -04:00
|
|
|
ok_future(serialize_response(
|
2018-09-05 22:13:36 -04:00
|
|
|
base.cmd_id(),
|
|
|
|
&mut builder,
|
|
|
|
msg::BaseArgs {
|
2018-10-03 21:12:23 -04:00
|
|
|
inner_type: msg::Any::StartRes,
|
|
|
|
inner: Some(inner.as_union_value()),
|
2018-08-13 19:55:10 -04:00
|
|
|
..Default::default()
|
|
|
|
},
|
2018-08-15 23:36:48 -04:00
|
|
|
))
|
2018-07-23 14:13:12 -04:00
|
|
|
}
|
|
|
|
|
2019-02-09 16:55:40 -05:00
|
|
|
fn op_format_error(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-02-09 16:55:40 -05:00
|
|
|
base: &msg::Base<'_>,
|
|
|
|
data: libdeno::deno_buf,
|
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
|
|
|
let inner = base.inner_as_format_error().unwrap();
|
|
|
|
let orig_error = String::from(inner.error().unwrap());
|
|
|
|
|
|
|
|
let js_error = JSError::from_v8_exception(&orig_error).unwrap();
|
2019-03-01 19:25:50 -05:00
|
|
|
let js_error_mapped = apply_source_map(&js_error, &isolate.state.dir);
|
2019-02-28 16:19:04 -05:00
|
|
|
let js_error_string = JSErrorColor(&js_error_mapped).to_string();
|
2019-02-09 16:55:40 -05:00
|
|
|
|
|
|
|
let mut builder = FlatBufferBuilder::new();
|
|
|
|
let new_error = builder.create_string(&js_error_string);
|
|
|
|
|
|
|
|
let inner = msg::FormatErrorRes::create(
|
|
|
|
&mut builder,
|
|
|
|
&msg::FormatErrorResArgs {
|
|
|
|
error: Some(new_error),
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
ok_future(serialize_response(
|
|
|
|
base.cmd_id(),
|
|
|
|
&mut builder,
|
|
|
|
msg::BaseArgs {
|
|
|
|
inner_type: msg::Any::FormatErrorRes,
|
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
2018-09-09 19:48:10 -04:00
|
|
|
fn serialize_response(
|
2018-09-05 22:13:36 -04:00
|
|
|
cmd_id: u32,
|
2019-01-14 01:30:38 -05:00
|
|
|
builder: &mut FlatBufferBuilder<'_>,
|
|
|
|
mut args: msg::BaseArgs<'_>,
|
2018-09-05 22:13:36 -04:00
|
|
|
) -> Buf {
|
|
|
|
args.cmd_id = cmd_id;
|
2018-08-17 15:11:28 -04:00
|
|
|
let base = msg::Base::create(builder, &args);
|
|
|
|
msg::finish_base_buffer(builder, base);
|
2018-09-02 01:58:23 -04:00
|
|
|
let data = builder.finished_data();
|
2018-09-09 19:48:10 -04:00
|
|
|
// println!("serialize_response {:x?}", data);
|
2018-12-04 23:36:10 -05:00
|
|
|
data.into()
|
2018-08-09 15:17:08 -04:00
|
|
|
}
|
|
|
|
|
2018-12-11 08:36:34 -05:00
|
|
|
#[inline]
|
2019-01-08 14:44:06 -05:00
|
|
|
pub fn ok_future(buf: Buf) -> Box<Op> {
|
2018-09-05 22:13:36 -04:00
|
|
|
Box::new(futures::future::ok(buf))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Shout out to Earl Sweatshirt.
|
2018-12-11 08:36:34 -05:00
|
|
|
#[inline]
|
2019-01-08 14:44:06 -05:00
|
|
|
pub fn odd_future(err: DenoError) -> Box<Op> {
|
2018-09-05 22:13:36 -04:00
|
|
|
Box::new(futures::future::err(err))
|
2018-08-09 15:17:08 -04:00
|
|
|
}
|
|
|
|
|
2018-10-06 23:06:20 -04:00
|
|
|
// https://github.com/denoland/deno/blob/golang/os.go#L100-L154
|
2019-02-18 10:42:15 -05:00
|
|
|
fn op_fetch_module_meta_data(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-09-27 17:33:10 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
2019-02-18 10:42:15 -05:00
|
|
|
let inner = base.inner_as_fetch_module_meta_data().unwrap();
|
2018-09-05 22:13:36 -04:00
|
|
|
let cmd_id = base.cmd_id();
|
2018-12-11 11:23:59 -05:00
|
|
|
let specifier = inner.specifier().unwrap();
|
|
|
|
let referrer = inner.referrer().unwrap();
|
2018-07-19 21:14:32 -04:00
|
|
|
|
2019-03-03 16:52:41 -05:00
|
|
|
// Check for allow read since this operation could be used to read from the file system.
|
2019-03-01 19:25:50 -05:00
|
|
|
if !isolate.permissions.allow_read.load(Ordering::SeqCst) {
|
|
|
|
debug!("No read permission for fetch_module_meta_data");
|
|
|
|
return odd_future(permission_denied());
|
|
|
|
}
|
|
|
|
|
2019-03-03 16:52:41 -05:00
|
|
|
// Check for allow write since this operation could be used to write to the file system.
|
|
|
|
if !isolate.permissions.allow_write.load(Ordering::SeqCst) {
|
|
|
|
debug!("No network permission for fetch_module_meta_data");
|
|
|
|
return odd_future(permission_denied());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check for allow net since this operation could be used to make https/http requests.
|
2019-03-01 19:25:50 -05:00
|
|
|
if !isolate.permissions.allow_net.load(Ordering::SeqCst) {
|
|
|
|
debug!("No network permission for fetch_module_meta_data");
|
|
|
|
return odd_future(permission_denied());
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
isolate.state.dir.root.join("gen"),
|
|
|
|
isolate.state.dir.gen,
|
|
|
|
"Sanity check"
|
|
|
|
);
|
2018-07-06 11:27:36 -04:00
|
|
|
|
2018-09-05 22:13:36 -04:00
|
|
|
Box::new(futures::future::result(|| -> OpResult {
|
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
2019-03-01 19:25:50 -05:00
|
|
|
let out = isolate
|
|
|
|
.state
|
|
|
|
.dir
|
|
|
|
.fetch_module_meta_data(specifier, referrer)?;
|
2019-02-18 10:42:15 -05:00
|
|
|
let data_off = builder.create_vector(out.source_code.as_slice());
|
|
|
|
let msg_args = msg::FetchModuleMetaDataResArgs {
|
2018-09-05 22:13:36 -04:00
|
|
|
module_name: Some(builder.create_string(&out.module_name)),
|
|
|
|
filename: Some(builder.create_string(&out.filename)),
|
2018-10-21 22:14:27 -04:00
|
|
|
media_type: out.media_type,
|
2019-02-18 10:42:15 -05:00
|
|
|
data: Some(data_off),
|
2018-09-05 22:13:36 -04:00
|
|
|
};
|
2019-02-18 10:42:15 -05:00
|
|
|
let inner = msg::FetchModuleMetaDataRes::create(builder, &msg_args);
|
2018-09-09 19:48:10 -04:00
|
|
|
Ok(serialize_response(
|
2018-09-05 22:13:36 -04:00
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
2018-10-03 21:12:23 -04:00
|
|
|
inner: Some(inner.as_union_value()),
|
2019-02-18 10:42:15 -05:00
|
|
|
inner_type: msg::Any::FetchModuleMetaDataRes,
|
2018-09-05 22:13:36 -04:00
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}()))
|
2018-07-13 03:24:07 -04:00
|
|
|
}
|
|
|
|
|
2018-10-13 16:03:27 -04:00
|
|
|
fn op_chdir(
|
2019-03-01 19:25:50 -05:00
|
|
|
_isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-10-13 16:03:27 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
|
|
|
let inner = base.inner_as_chdir().unwrap();
|
|
|
|
let directory = inner.directory().unwrap();
|
|
|
|
Box::new(futures::future::result(|| -> OpResult {
|
2018-11-04 09:04:24 -05:00
|
|
|
std::env::set_current_dir(&directory)?;
|
2018-10-13 16:03:27 -04:00
|
|
|
Ok(empty_buf())
|
|
|
|
}()))
|
|
|
|
}
|
|
|
|
|
2019-03-10 15:37:05 -04:00
|
|
|
fn op_global_timer_stop(
|
2018-12-04 23:36:10 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-09-27 17:33:10 -04:00
|
|
|
) -> Box<Op> {
|
2019-03-10 15:37:05 -04:00
|
|
|
assert!(base.sync());
|
2018-09-27 17:33:10 -04:00
|
|
|
assert_eq!(data.len(), 0);
|
2019-03-10 15:37:05 -04:00
|
|
|
let mut t = isolate.state.global_timer.lock().unwrap();
|
|
|
|
t.cancel();
|
2018-09-24 22:46:36 -04:00
|
|
|
ok_future(empty_buf())
|
|
|
|
}
|
|
|
|
|
2019-03-10 15:37:05 -04:00
|
|
|
fn op_global_timer(
|
|
|
|
isolate: &Isolate,
|
|
|
|
base: &msg::Base<'_>,
|
|
|
|
data: libdeno::deno_buf,
|
|
|
|
) -> Box<Op> {
|
|
|
|
assert!(!base.sync());
|
|
|
|
assert_eq!(data.len(), 0);
|
|
|
|
let cmd_id = base.cmd_id();
|
|
|
|
let inner = base.inner_as_global_timer().unwrap();
|
|
|
|
let val = inner.timeout();
|
|
|
|
assert!(val >= 0);
|
|
|
|
|
|
|
|
let mut t = isolate.state.global_timer.lock().unwrap();
|
|
|
|
let deadline = Instant::now() + Duration::from_millis(val as u64);
|
|
|
|
let f = t.new_timeout(deadline);
|
|
|
|
|
|
|
|
Box::new(f.then(move |_| {
|
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
let inner =
|
|
|
|
msg::GlobalTimerRes::create(builder, &msg::GlobalTimerResArgs {});
|
|
|
|
Ok(serialize_response(
|
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::GlobalTimerRes,
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_set_env(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-09-27 17:33:10 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = base.inner_as_set_env().unwrap();
|
|
|
|
let key = inner.key().unwrap();
|
|
|
|
let value = inner.value().unwrap();
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_env() {
|
2018-10-27 09:11:39 -04:00
|
|
|
return odd_future(e);
|
2018-08-31 07:51:12 -04:00
|
|
|
}
|
|
|
|
std::env::set_var(key, value);
|
2018-09-18 14:53:16 -04:00
|
|
|
ok_future(empty_buf())
|
2018-08-31 07:51:12 -04:00
|
|
|
}
|
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_env(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-09-27 17:33:10 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
2018-09-05 22:13:36 -04:00
|
|
|
let cmd_id = base.cmd_id();
|
2018-09-18 14:53:16 -04:00
|
|
|
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_env() {
|
2018-10-27 09:11:39 -04:00
|
|
|
return odd_future(e);
|
2018-08-31 07:51:12 -04:00
|
|
|
}
|
|
|
|
|
2018-09-05 22:13:36 -04:00
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
2018-09-02 01:59:16 -04:00
|
|
|
let vars: Vec<_> = std::env::vars()
|
2018-11-02 20:09:10 -04:00
|
|
|
.map(|(key, value)| msg_util::serialize_key_value(builder, &key, &value))
|
|
|
|
.collect();
|
2018-09-02 01:58:23 -04:00
|
|
|
let tables = builder.create_vector(&vars);
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = msg::EnvironRes::create(
|
2018-08-31 07:51:12 -04:00
|
|
|
builder,
|
2018-11-04 09:04:24 -05:00
|
|
|
&msg::EnvironResArgs { map: Some(tables) },
|
2018-08-31 07:51:12 -04:00
|
|
|
);
|
2018-09-09 19:48:10 -04:00
|
|
|
ok_future(serialize_response(
|
2018-09-05 22:13:36 -04:00
|
|
|
cmd_id,
|
2018-08-31 07:51:12 -04:00
|
|
|
builder,
|
2018-09-05 22:13:36 -04:00
|
|
|
msg::BaseArgs {
|
2018-10-03 21:12:23 -04:00
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::EnvironRes,
|
2018-08-31 07:51:12 -04:00
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
2019-03-04 11:04:19 -05:00
|
|
|
fn op_permissions(
|
|
|
|
isolate: &Isolate,
|
|
|
|
base: &msg::Base<'_>,
|
|
|
|
data: libdeno::deno_buf,
|
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
|
|
|
let cmd_id = base.cmd_id();
|
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
let inner = msg::PermissionsRes::create(
|
|
|
|
builder,
|
|
|
|
&msg::PermissionsResArgs {
|
|
|
|
run: isolate.permissions.allows_run(),
|
|
|
|
read: isolate.permissions.allows_read(),
|
|
|
|
write: isolate.permissions.allows_write(),
|
|
|
|
net: isolate.permissions.allows_net(),
|
|
|
|
env: isolate.permissions.allows_env(),
|
|
|
|
},
|
|
|
|
);
|
|
|
|
ok_future(serialize_response(
|
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::PermissionsRes,
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn op_revoke_permission(
|
|
|
|
isolate: &Isolate,
|
|
|
|
base: &msg::Base<'_>,
|
|
|
|
data: libdeno::deno_buf,
|
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
|
|
|
let inner = base.inner_as_permission_revoke().unwrap();
|
|
|
|
let permission = inner.permission().unwrap();
|
|
|
|
let result = match permission {
|
|
|
|
"run" => isolate.permissions.revoke_run(),
|
|
|
|
"read" => isolate.permissions.revoke_read(),
|
|
|
|
"write" => isolate.permissions.revoke_write(),
|
|
|
|
"net" => isolate.permissions.revoke_net(),
|
|
|
|
"env" => isolate.permissions.revoke_env(),
|
|
|
|
_ => Ok(()),
|
|
|
|
};
|
|
|
|
if let Err(e) = result {
|
|
|
|
return odd_future(e);
|
|
|
|
}
|
|
|
|
ok_future(empty_buf())
|
|
|
|
}
|
|
|
|
|
2018-10-30 15:02:18 -04:00
|
|
|
fn op_fetch(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-09-27 17:33:10 -04:00
|
|
|
) -> Box<Op> {
|
2018-10-30 15:02:18 -04:00
|
|
|
let inner = base.inner_as_fetch().unwrap();
|
2018-09-05 22:13:36 -04:00
|
|
|
let cmd_id = base.cmd_id();
|
2018-11-14 20:36:34 -05:00
|
|
|
|
|
|
|
let header = inner.header().unwrap();
|
|
|
|
assert!(header.is_request());
|
|
|
|
let url = header.url().unwrap();
|
|
|
|
|
2018-11-30 03:30:49 -05:00
|
|
|
let body = if data.is_empty() {
|
2018-11-14 21:19:38 -05:00
|
|
|
hyper::Body::empty()
|
|
|
|
} else {
|
2018-12-04 16:21:02 -05:00
|
|
|
hyper::Body::from(Vec::from(&*data))
|
2018-11-14 21:19:38 -05:00
|
|
|
};
|
|
|
|
|
2018-12-21 04:47:09 -05:00
|
|
|
let maybe_req = msg_util::deserialize_request(header, body);
|
|
|
|
if let Err(e) = maybe_req {
|
|
|
|
return odd_future(e);
|
|
|
|
}
|
|
|
|
let req = maybe_req.unwrap();
|
2018-09-05 22:13:36 -04:00
|
|
|
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_net(url) {
|
2018-10-27 09:11:39 -04:00
|
|
|
return odd_future(e);
|
2018-09-05 22:13:36 -04:00
|
|
|
}
|
|
|
|
|
2018-10-26 11:01:43 -04:00
|
|
|
let client = http_util::get_client();
|
2018-08-15 20:57:36 -04:00
|
|
|
|
2018-09-18 14:53:16 -04:00
|
|
|
debug!("Before fetch {}", url);
|
2018-11-14 20:36:34 -05:00
|
|
|
let future =
|
|
|
|
client
|
|
|
|
.request(req)
|
|
|
|
.map_err(DenoError::from)
|
|
|
|
.and_then(move |res| {
|
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
let header_off = msg_util::serialize_http_response(builder, &res);
|
|
|
|
let body = res.into_body();
|
|
|
|
let body_resource = resources::add_hyper_body(body);
|
|
|
|
let inner = msg::FetchRes::create(
|
|
|
|
builder,
|
|
|
|
&msg::FetchResArgs {
|
|
|
|
header: Some(header_off),
|
|
|
|
body_rid: body_resource.rid,
|
|
|
|
},
|
|
|
|
);
|
2018-09-12 15:16:42 -04:00
|
|
|
|
2018-11-14 20:36:34 -05:00
|
|
|
Ok(serialize_response(
|
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::FetchRes,
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
});
|
2018-09-05 22:13:36 -04:00
|
|
|
Box::new(future)
|
2018-08-15 20:57:36 -04:00
|
|
|
}
|
|
|
|
|
2018-09-22 04:42:07 -04:00
|
|
|
// This is just type conversion. Implement From trait?
|
|
|
|
// See https://github.com/tokio-rs/tokio/blob/ffd73a64e7ec497622b7f939e38017afe7124dc4/tokio-fs/src/lib.rs#L76-L85
|
|
|
|
fn convert_blocking<F>(f: F) -> Poll<Buf, DenoError>
|
|
|
|
where
|
|
|
|
F: FnOnce() -> DenoResult<Buf>,
|
|
|
|
{
|
|
|
|
use futures::Async::*;
|
|
|
|
match tokio_threadpool::blocking(f) {
|
|
|
|
Ok(Ready(Ok(v))) => Ok(v.into()),
|
|
|
|
Ok(Ready(Err(err))) => Err(err),
|
|
|
|
Ok(NotReady) => Ok(NotReady),
|
2018-11-04 09:04:24 -05:00
|
|
|
Err(_err) => panic!("blocking error"),
|
2018-09-22 04:42:07 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-11 08:36:34 -05:00
|
|
|
fn blocking<F>(is_sync: bool, f: F) -> Box<Op>
|
|
|
|
where
|
|
|
|
F: 'static + Send + FnOnce() -> DenoResult<Buf>,
|
|
|
|
{
|
|
|
|
if is_sync {
|
|
|
|
Box::new(futures::future::result(f()))
|
|
|
|
} else {
|
|
|
|
Box::new(tokio_util::poll_fn(move || convert_blocking(f)))
|
|
|
|
}
|
2018-09-22 04:42:07 -04:00
|
|
|
}
|
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_make_temp_dir(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-09-27 17:33:10 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
2018-09-05 22:13:36 -04:00
|
|
|
let base = Box::new(*base);
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = base.inner_as_make_temp_dir().unwrap();
|
2018-09-05 22:13:36 -04:00
|
|
|
let cmd_id = base.cmd_id();
|
|
|
|
|
2018-10-27 09:11:39 -04:00
|
|
|
// FIXME
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_write("make_temp") {
|
2018-10-27 09:11:39 -04:00
|
|
|
return odd_future(e);
|
2018-08-23 18:36:45 -04:00
|
|
|
}
|
2018-09-22 04:42:07 -04:00
|
|
|
|
2018-10-03 21:12:23 -04:00
|
|
|
let dir = inner.dir().map(PathBuf::from);
|
|
|
|
let prefix = inner.prefix().map(String::from);
|
|
|
|
let suffix = inner.suffix().map(String::from);
|
2018-09-22 04:42:07 -04:00
|
|
|
|
2018-12-11 08:36:34 -05:00
|
|
|
blocking(base.sync(), move || -> OpResult {
|
2018-09-05 22:13:36 -04:00
|
|
|
// TODO(piscisaureus): use byte vector for paths, not a string.
|
2018-10-06 23:06:20 -04:00
|
|
|
// See https://github.com/denoland/deno/issues/627.
|
2018-09-05 22:13:36 -04:00
|
|
|
// We can't assume that paths are always valid utf8 strings.
|
2018-09-22 04:42:07 -04:00
|
|
|
let path = deno_fs::make_temp_dir(
|
|
|
|
// Converting Option<String> to Option<&str>
|
|
|
|
dir.as_ref().map(|x| &**x),
|
|
|
|
prefix.as_ref().map(|x| &**x),
|
|
|
|
suffix.as_ref().map(|x| &**x),
|
|
|
|
)?;
|
2018-09-05 22:13:36 -04:00
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
let path_off = builder.create_string(path.to_str().unwrap());
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = msg::MakeTempDirRes::create(
|
2018-09-05 22:13:36 -04:00
|
|
|
builder,
|
|
|
|
&msg::MakeTempDirResArgs {
|
|
|
|
path: Some(path_off),
|
|
|
|
},
|
|
|
|
);
|
2018-09-09 19:48:10 -04:00
|
|
|
Ok(serialize_response(
|
2018-09-05 22:13:36 -04:00
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
2018-10-03 21:12:23 -04:00
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::MakeTempDirRes,
|
2018-09-05 22:13:36 -04:00
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
2018-09-22 04:42:07 -04:00
|
|
|
})
|
2018-08-23 18:36:45 -04:00
|
|
|
}
|
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_mkdir(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-09-27 17:33:10 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = base.inner_as_mkdir().unwrap();
|
|
|
|
let path = String::from(inner.path().unwrap());
|
2019-01-17 23:39:06 -05:00
|
|
|
let recursive = inner.recursive();
|
|
|
|
let mode = inner.mode();
|
2018-09-18 14:53:16 -04:00
|
|
|
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_write(&path) {
|
2018-10-27 09:11:39 -04:00
|
|
|
return odd_future(e);
|
2018-09-05 22:13:36 -04:00
|
|
|
}
|
2019-01-17 23:39:06 -05:00
|
|
|
|
2018-12-11 08:36:34 -05:00
|
|
|
blocking(base.sync(), move || {
|
2018-10-03 20:48:02 -04:00
|
|
|
debug!("op_mkdir {}", path);
|
2019-01-17 23:39:06 -05:00
|
|
|
deno_fs::mkdir(Path::new(&path), mode, recursive)?;
|
2018-09-18 14:53:16 -04:00
|
|
|
Ok(empty_buf())
|
2018-09-22 04:42:07 -04:00
|
|
|
})
|
2018-08-26 02:26:30 -04:00
|
|
|
}
|
|
|
|
|
2018-10-26 16:01:45 -04:00
|
|
|
fn op_chmod(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-10-26 16:01:45 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
|
|
|
let inner = base.inner_as_chmod().unwrap();
|
|
|
|
let _mode = inner.mode();
|
|
|
|
let path = String::from(inner.path().unwrap());
|
|
|
|
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_write(&path) {
|
2018-10-27 09:11:39 -04:00
|
|
|
return odd_future(e);
|
2018-10-26 16:01:45 -04:00
|
|
|
}
|
|
|
|
|
2018-12-11 08:36:34 -05:00
|
|
|
blocking(base.sync(), move || {
|
2018-10-26 16:01:45 -04:00
|
|
|
debug!("op_chmod {}", &path);
|
|
|
|
let path = PathBuf::from(&path);
|
|
|
|
// Still check file/dir exists on windows
|
|
|
|
let _metadata = fs::metadata(&path)?;
|
|
|
|
// Only work in unix
|
|
|
|
#[cfg(any(unix))]
|
|
|
|
{
|
2018-11-05 01:21:21 -05:00
|
|
|
// We need to use underscore to compile in Windows.
|
2019-02-08 11:14:33 -05:00
|
|
|
#[cfg_attr(
|
|
|
|
feature = "cargo-clippy",
|
|
|
|
allow(clippy::used_underscore_binding)
|
|
|
|
)]
|
2018-10-26 16:01:45 -04:00
|
|
|
let mut permissions = _metadata.permissions();
|
2019-02-08 11:14:33 -05:00
|
|
|
#[cfg_attr(
|
|
|
|
feature = "cargo-clippy",
|
|
|
|
allow(clippy::used_underscore_binding)
|
|
|
|
)]
|
2018-10-26 16:01:45 -04:00
|
|
|
permissions.set_mode(_mode);
|
|
|
|
fs::set_permissions(&path, permissions)?;
|
|
|
|
}
|
|
|
|
Ok(empty_buf())
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_open(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-09-27 00:56:39 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
|
|
|
let cmd_id = base.cmd_id();
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = base.inner_as_open().unwrap();
|
2018-12-13 16:20:37 -05:00
|
|
|
let filename_str = inner.filename().unwrap();
|
|
|
|
let filename = PathBuf::from(&filename_str);
|
2018-12-12 12:05:58 -05:00
|
|
|
let mode = inner.mode().unwrap();
|
2018-09-27 00:56:39 -04:00
|
|
|
|
2018-12-12 12:05:58 -05:00
|
|
|
let mut open_options = tokio::fs::OpenOptions::new();
|
|
|
|
|
|
|
|
match mode {
|
|
|
|
"r" => {
|
|
|
|
open_options.read(true);
|
|
|
|
}
|
|
|
|
"r+" => {
|
|
|
|
open_options.read(true).write(true);
|
|
|
|
}
|
|
|
|
"w" => {
|
|
|
|
open_options.create(true).write(true).truncate(true);
|
|
|
|
}
|
|
|
|
"w+" => {
|
|
|
|
open_options
|
|
|
|
.read(true)
|
|
|
|
.create(true)
|
|
|
|
.write(true)
|
|
|
|
.truncate(true);
|
|
|
|
}
|
|
|
|
"a" => {
|
|
|
|
open_options.create(true).append(true);
|
|
|
|
}
|
|
|
|
"a+" => {
|
|
|
|
open_options.read(true).create(true).append(true);
|
|
|
|
}
|
|
|
|
"x" => {
|
|
|
|
open_options.create_new(true).write(true);
|
|
|
|
}
|
|
|
|
"x+" => {
|
|
|
|
open_options.create_new(true).read(true).write(true);
|
|
|
|
}
|
|
|
|
&_ => {
|
|
|
|
panic!("Unknown file open mode.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-08 15:59:38 -05:00
|
|
|
match mode {
|
|
|
|
"r" => {
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_read(&filename_str) {
|
2019-02-08 15:59:38 -05:00
|
|
|
return odd_future(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"w" | "a" | "x" => {
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_write(&filename_str) {
|
2019-02-08 15:59:38 -05:00
|
|
|
return odd_future(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
&_ => {
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_read(&filename_str) {
|
2019-02-08 15:59:38 -05:00
|
|
|
return odd_future(e);
|
|
|
|
}
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_write(&filename_str) {
|
2019-02-08 15:59:38 -05:00
|
|
|
return odd_future(e);
|
|
|
|
}
|
2018-12-14 03:29:17 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-12 12:05:58 -05:00
|
|
|
let op = open_options
|
|
|
|
.open(filename)
|
2018-11-04 09:04:24 -05:00
|
|
|
.map_err(DenoError::from)
|
2018-09-27 00:56:39 -04:00
|
|
|
.and_then(move |fs_file| -> OpResult {
|
2018-10-01 19:37:18 -04:00
|
|
|
let resource = resources::add_fs_file(fs_file);
|
2018-09-27 00:56:39 -04:00
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
2018-11-04 09:04:24 -05:00
|
|
|
let inner =
|
|
|
|
msg::OpenRes::create(builder, &msg::OpenResArgs { rid: resource.rid });
|
2018-09-27 00:56:39 -04:00
|
|
|
Ok(serialize_response(
|
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
2018-10-03 21:12:23 -04:00
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::OpenRes,
|
2018-09-27 00:56:39 -04:00
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
});
|
|
|
|
Box::new(op)
|
|
|
|
}
|
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_close(
|
2019-03-01 19:25:50 -05:00
|
|
|
_isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-10-03 23:58:29 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
2018-10-03 21:41:59 -04:00
|
|
|
let inner = base.inner_as_close().unwrap();
|
|
|
|
let rid = inner.rid();
|
2018-10-03 23:58:29 -04:00
|
|
|
match resources::lookup(rid) {
|
2018-10-05 10:20:51 -04:00
|
|
|
None => odd_future(errors::bad_resource()),
|
2019-01-09 12:59:46 -05:00
|
|
|
Some(resource) => {
|
2018-10-03 23:58:29 -04:00
|
|
|
resource.close();
|
|
|
|
ok_future(empty_buf())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-05 12:16:24 -04:00
|
|
|
fn op_shutdown(
|
2019-03-01 19:25:50 -05:00
|
|
|
_isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-10-05 12:16:24 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
|
|
|
let inner = base.inner_as_shutdown().unwrap();
|
|
|
|
let rid = inner.rid();
|
|
|
|
let how = inner.how();
|
|
|
|
match resources::lookup(rid) {
|
2018-10-10 11:15:47 -04:00
|
|
|
None => odd_future(errors::bad_resource()),
|
2018-10-05 12:16:24 -04:00
|
|
|
Some(mut resource) => {
|
|
|
|
let shutdown_mode = match how {
|
|
|
|
0 => Shutdown::Read,
|
|
|
|
1 => Shutdown::Write,
|
|
|
|
_ => unimplemented!(),
|
|
|
|
};
|
2018-12-11 08:36:34 -05:00
|
|
|
blocking(base.sync(), move || {
|
2018-10-05 12:16:24 -04:00
|
|
|
// Use UFCS for disambiguation
|
|
|
|
Resource::shutdown(&mut resource, shutdown_mode)?;
|
|
|
|
Ok(empty_buf())
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_read(
|
2019-03-01 19:25:50 -05:00
|
|
|
_isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-09-27 00:56:39 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
let cmd_id = base.cmd_id();
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = base.inner_as_read().unwrap();
|
|
|
|
let rid = inner.rid();
|
2018-09-27 00:56:39 -04:00
|
|
|
|
2018-10-01 19:37:18 -04:00
|
|
|
match resources::lookup(rid) {
|
2018-10-05 10:20:51 -04:00
|
|
|
None => odd_future(errors::bad_resource()),
|
2018-10-01 19:43:27 -04:00
|
|
|
Some(resource) => {
|
2018-10-19 11:40:54 -04:00
|
|
|
let op = resources::eager_read(resource, data)
|
2018-11-04 09:04:24 -05:00
|
|
|
.map_err(DenoError::from)
|
2018-10-01 19:43:27 -04:00
|
|
|
.and_then(move |(_resource, _buf, nread)| {
|
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = msg::ReadRes::create(
|
2018-10-01 19:43:27 -04:00
|
|
|
builder,
|
|
|
|
&msg::ReadResArgs {
|
|
|
|
nread: nread as u32,
|
|
|
|
eof: nread == 0,
|
|
|
|
},
|
|
|
|
);
|
|
|
|
Ok(serialize_response(
|
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
2018-10-03 21:12:23 -04:00
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::ReadRes,
|
2018-10-01 19:43:27 -04:00
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
});
|
2018-09-27 00:56:39 -04:00
|
|
|
Box::new(op)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_write(
|
2019-03-01 19:25:50 -05:00
|
|
|
_isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-09-27 00:56:39 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
let cmd_id = base.cmd_id();
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = base.inner_as_write().unwrap();
|
|
|
|
let rid = inner.rid();
|
2018-09-27 00:56:39 -04:00
|
|
|
|
2018-10-01 19:37:18 -04:00
|
|
|
match resources::lookup(rid) {
|
2018-10-05 10:20:51 -04:00
|
|
|
None => odd_future(errors::bad_resource()),
|
2018-10-01 19:43:27 -04:00
|
|
|
Some(resource) => {
|
2018-10-19 18:17:48 -04:00
|
|
|
let op = resources::eager_write(resource, data)
|
2018-11-04 09:04:24 -05:00
|
|
|
.map_err(DenoError::from)
|
2018-10-19 16:10:25 -04:00
|
|
|
.and_then(move |(_resource, _buf, nwritten)| {
|
2018-10-01 19:43:27 -04:00
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = msg::WriteRes::create(
|
2018-10-01 19:43:27 -04:00
|
|
|
builder,
|
|
|
|
&msg::WriteResArgs {
|
2018-10-19 16:10:25 -04:00
|
|
|
nbyte: nwritten as u32,
|
2018-10-01 19:43:27 -04:00
|
|
|
},
|
|
|
|
);
|
|
|
|
Ok(serialize_response(
|
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
2018-10-03 21:12:23 -04:00
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::WriteRes,
|
2018-10-01 19:43:27 -04:00
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
});
|
2018-09-27 00:56:39 -04:00
|
|
|
Box::new(op)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-18 18:26:41 -05:00
|
|
|
fn op_seek(
|
2019-03-01 19:25:50 -05:00
|
|
|
_isolate: &Isolate,
|
2019-02-18 18:26:41 -05:00
|
|
|
base: &msg::Base<'_>,
|
|
|
|
data: libdeno::deno_buf,
|
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
|
|
|
let _cmd_id = base.cmd_id();
|
|
|
|
let inner = base.inner_as_seek().unwrap();
|
|
|
|
let rid = inner.rid();
|
|
|
|
let offset = inner.offset();
|
|
|
|
let whence = inner.whence();
|
|
|
|
|
|
|
|
match resources::lookup(rid) {
|
|
|
|
None => odd_future(errors::bad_resource()),
|
|
|
|
Some(resource) => {
|
|
|
|
let op = resources::seek(resource, offset, whence)
|
|
|
|
.and_then(move |_| Ok(empty_buf()));
|
|
|
|
Box::new(op)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_remove(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-09-27 17:33:10 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = base.inner_as_remove().unwrap();
|
2018-10-27 09:11:39 -04:00
|
|
|
let path_ = inner.path().unwrap();
|
|
|
|
let path = PathBuf::from(path_);
|
2018-10-03 21:12:23 -04:00
|
|
|
let recursive = inner.recursive();
|
2018-10-27 09:11:39 -04:00
|
|
|
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_write(path.to_str().unwrap()) {
|
2018-10-27 09:11:39 -04:00
|
|
|
return odd_future(e);
|
2018-09-10 23:40:03 -04:00
|
|
|
}
|
2018-10-27 09:11:39 -04:00
|
|
|
|
2018-12-11 08:36:34 -05:00
|
|
|
blocking(base.sync(), move || {
|
2018-10-03 20:48:02 -04:00
|
|
|
debug!("op_remove {}", path.display());
|
2018-09-22 04:42:07 -04:00
|
|
|
let metadata = fs::metadata(&path)?;
|
2018-09-10 23:40:03 -04:00
|
|
|
if metadata.is_file() {
|
2018-09-22 04:42:07 -04:00
|
|
|
fs::remove_file(&path)?;
|
2018-11-04 09:04:24 -05:00
|
|
|
} else if recursive {
|
|
|
|
remove_dir_all(&path)?;
|
2018-09-10 23:40:03 -04:00
|
|
|
} else {
|
2018-11-04 09:04:24 -05:00
|
|
|
fs::remove_dir(&path)?;
|
2018-09-10 23:40:03 -04:00
|
|
|
}
|
2018-09-18 14:53:16 -04:00
|
|
|
Ok(empty_buf())
|
2018-09-22 04:42:07 -04:00
|
|
|
})
|
2018-09-10 23:40:03 -04:00
|
|
|
}
|
|
|
|
|
2018-10-06 23:06:20 -04:00
|
|
|
// Prototype https://github.com/denoland/deno/blob/golang/os.go#L171-L184
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_read_file(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-09-27 17:33:10 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = base.inner_as_read_file().unwrap();
|
2018-09-05 22:13:36 -04:00
|
|
|
let cmd_id = base.cmd_id();
|
2019-02-08 15:59:38 -05:00
|
|
|
let filename_ = inner.filename().unwrap();
|
|
|
|
let filename = PathBuf::from(filename_);
|
2018-10-03 20:48:02 -04:00
|
|
|
debug!("op_read_file {}", filename.display());
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_read(&filename_) {
|
2019-02-08 15:59:38 -05:00
|
|
|
return odd_future(e);
|
|
|
|
}
|
2018-12-11 08:36:34 -05:00
|
|
|
blocking(base.sync(), move || {
|
2018-09-22 04:42:07 -04:00
|
|
|
let vec = fs::read(&filename)?;
|
2018-10-03 21:12:23 -04:00
|
|
|
// Build the response message. memcpy data into inner.
|
2018-09-05 22:13:36 -04:00
|
|
|
// TODO(ry) zero-copy.
|
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
let data_off = builder.create_vector(vec.as_slice());
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = msg::ReadFileRes::create(
|
2018-09-05 22:13:36 -04:00
|
|
|
builder,
|
2018-09-09 20:25:43 -04:00
|
|
|
&msg::ReadFileResArgs {
|
2018-09-05 22:13:36 -04:00
|
|
|
data: Some(data_off),
|
|
|
|
},
|
|
|
|
);
|
2018-09-09 19:48:10 -04:00
|
|
|
Ok(serialize_response(
|
2018-09-05 22:13:36 -04:00
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
2018-10-03 21:12:23 -04:00
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::ReadFileRes,
|
2018-09-05 22:13:36 -04:00
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
2018-09-22 04:42:07 -04:00
|
|
|
})
|
2018-08-09 13:24:30 -04:00
|
|
|
}
|
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_copy_file(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-09-30 18:06:41 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = base.inner_as_copy_file().unwrap();
|
2019-02-08 15:59:38 -05:00
|
|
|
let from_ = inner.from().unwrap();
|
|
|
|
let from = PathBuf::from(from_);
|
2018-10-27 09:11:39 -04:00
|
|
|
let to_ = inner.to().unwrap();
|
|
|
|
let to = PathBuf::from(to_);
|
2018-09-30 18:06:41 -04:00
|
|
|
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_read(&from_) {
|
2019-02-08 15:59:38 -05:00
|
|
|
return odd_future(e);
|
|
|
|
}
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_write(&to_) {
|
2018-10-27 09:11:39 -04:00
|
|
|
return odd_future(e);
|
2018-09-30 18:06:41 -04:00
|
|
|
}
|
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
debug!("op_copy_file {} {}", from.display(), to.display());
|
2018-12-11 08:36:34 -05:00
|
|
|
blocking(base.sync(), move || {
|
2018-10-17 01:40:03 -04:00
|
|
|
// On *nix, Rust deem non-existent path as invalid input
|
|
|
|
// See https://github.com/rust-lang/rust/issues/54800
|
|
|
|
// Once the issue is reolved, we should remove this workaround.
|
|
|
|
if cfg!(unix) && !from.is_file() {
|
|
|
|
return Err(errors::new(
|
2018-10-17 13:04:28 -04:00
|
|
|
ErrorKind::NotFound,
|
|
|
|
"File not found".to_string(),
|
2018-10-17 01:40:03 -04:00
|
|
|
));
|
|
|
|
}
|
|
|
|
|
2018-09-30 18:06:41 -04:00
|
|
|
fs::copy(&from, &to)?;
|
|
|
|
Ok(empty_buf())
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2018-08-29 09:22:25 -04:00
|
|
|
macro_rules! to_seconds {
|
|
|
|
($time:expr) => {{
|
|
|
|
// Unwrap is safe here as if the file is before the unix epoch
|
|
|
|
// something is very wrong.
|
2018-08-30 13:54:56 -04:00
|
|
|
$time
|
|
|
|
.and_then(|t| Ok(t.duration_since(UNIX_EPOCH).unwrap().as_secs()))
|
|
|
|
.unwrap_or(0)
|
|
|
|
}};
|
2018-08-29 09:22:25 -04:00
|
|
|
}
|
|
|
|
|
2018-09-12 10:28:48 -04:00
|
|
|
#[cfg(any(unix))]
|
2018-11-04 09:04:24 -05:00
|
|
|
fn get_mode(perm: &fs::Permissions) -> u32 {
|
2018-09-17 19:53:55 -04:00
|
|
|
perm.mode()
|
2018-09-12 10:28:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(any(unix)))]
|
2018-11-04 09:04:24 -05:00
|
|
|
fn get_mode(_perm: &fs::Permissions) -> u32 {
|
2018-09-17 19:53:55 -04:00
|
|
|
0
|
2018-09-12 10:28:48 -04:00
|
|
|
}
|
|
|
|
|
2018-10-13 16:03:27 -04:00
|
|
|
fn op_cwd(
|
2019-03-01 19:25:50 -05:00
|
|
|
_isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-10-13 16:03:27 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
|
|
|
let cmd_id = base.cmd_id();
|
|
|
|
Box::new(futures::future::result(|| -> OpResult {
|
|
|
|
let path = std::env::current_dir()?;
|
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
let cwd =
|
|
|
|
builder.create_string(&path.into_os_string().into_string().unwrap());
|
2018-11-04 09:04:24 -05:00
|
|
|
let inner =
|
|
|
|
msg::CwdRes::create(builder, &msg::CwdResArgs { cwd: Some(cwd) });
|
2018-10-13 16:03:27 -04:00
|
|
|
Ok(serialize_response(
|
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::CwdRes,
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}()))
|
|
|
|
}
|
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_stat(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-09-27 17:33:10 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = base.inner_as_stat().unwrap();
|
2018-09-05 22:13:36 -04:00
|
|
|
let cmd_id = base.cmd_id();
|
2019-02-08 15:59:38 -05:00
|
|
|
let filename_ = inner.filename().unwrap();
|
|
|
|
let filename = PathBuf::from(filename_);
|
2018-10-03 21:12:23 -04:00
|
|
|
let lstat = inner.lstat();
|
2018-09-02 02:33:24 -04:00
|
|
|
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_read(&filename_) {
|
2019-02-08 15:59:38 -05:00
|
|
|
return odd_future(e);
|
|
|
|
}
|
|
|
|
|
2018-12-11 08:36:34 -05:00
|
|
|
blocking(base.sync(), move || {
|
2018-09-05 22:13:36 -04:00
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
2018-10-03 20:48:02 -04:00
|
|
|
debug!("op_stat {} {}", filename.display(), lstat);
|
2018-09-05 22:13:36 -04:00
|
|
|
let metadata = if lstat {
|
2018-09-22 04:42:07 -04:00
|
|
|
fs::symlink_metadata(&filename)?
|
2018-09-05 22:13:36 -04:00
|
|
|
} else {
|
2018-09-22 04:42:07 -04:00
|
|
|
fs::metadata(&filename)?
|
2018-09-05 22:13:36 -04:00
|
|
|
};
|
|
|
|
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = msg::StatRes::create(
|
2018-09-05 22:13:36 -04:00
|
|
|
builder,
|
2018-09-11 15:38:53 -04:00
|
|
|
&msg::StatResArgs {
|
2018-09-05 22:13:36 -04:00
|
|
|
is_file: metadata.is_file(),
|
|
|
|
is_symlink: metadata.file_type().is_symlink(),
|
|
|
|
len: metadata.len(),
|
|
|
|
modified: to_seconds!(metadata.modified()),
|
|
|
|
accessed: to_seconds!(metadata.accessed()),
|
|
|
|
created: to_seconds!(metadata.created()),
|
2018-11-04 09:04:24 -05:00
|
|
|
mode: get_mode(&metadata.permissions()),
|
2018-09-17 19:53:55 -04:00
|
|
|
has_mode: cfg!(target_family = "unix"),
|
2018-09-05 22:13:36 -04:00
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
);
|
2018-08-29 09:22:25 -04:00
|
|
|
|
2018-09-09 19:48:10 -04:00
|
|
|
Ok(serialize_response(
|
2018-09-05 22:13:36 -04:00
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
2018-10-03 21:12:23 -04:00
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::StatRes,
|
2018-09-05 22:13:36 -04:00
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
2018-09-22 04:42:07 -04:00
|
|
|
})
|
2018-08-29 09:22:25 -04:00
|
|
|
}
|
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_read_dir(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-10-03 17:56:56 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = base.inner_as_read_dir().unwrap();
|
2018-10-03 17:56:56 -04:00
|
|
|
let cmd_id = base.cmd_id();
|
2018-10-03 21:12:23 -04:00
|
|
|
let path = String::from(inner.path().unwrap());
|
2018-10-03 17:56:56 -04:00
|
|
|
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_read(&path) {
|
2019-02-08 15:59:38 -05:00
|
|
|
return odd_future(e);
|
|
|
|
}
|
|
|
|
|
2018-12-11 08:36:34 -05:00
|
|
|
blocking(base.sync(), move || -> OpResult {
|
2018-10-03 20:48:02 -04:00
|
|
|
debug!("op_read_dir {}", path);
|
2018-10-03 17:56:56 -04:00
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
let entries: Vec<_> = fs::read_dir(Path::new(&path))?
|
|
|
|
.map(|entry| {
|
|
|
|
let entry = entry.unwrap();
|
|
|
|
let metadata = entry.metadata().unwrap();
|
|
|
|
let file_type = metadata.file_type();
|
|
|
|
let name = builder.create_string(entry.file_name().to_str().unwrap());
|
|
|
|
let path = builder.create_string(entry.path().to_str().unwrap());
|
|
|
|
|
|
|
|
msg::StatRes::create(
|
|
|
|
builder,
|
|
|
|
&msg::StatResArgs {
|
|
|
|
is_file: file_type.is_file(),
|
|
|
|
is_symlink: file_type.is_symlink(),
|
|
|
|
len: metadata.len(),
|
|
|
|
modified: to_seconds!(metadata.modified()),
|
|
|
|
accessed: to_seconds!(metadata.accessed()),
|
|
|
|
created: to_seconds!(metadata.created()),
|
|
|
|
name: Some(name),
|
|
|
|
path: Some(path),
|
2018-12-12 02:31:18 -05:00
|
|
|
mode: get_mode(&metadata.permissions()),
|
|
|
|
has_mode: cfg!(target_family = "unix"),
|
2018-10-03 17:56:56 -04:00
|
|
|
},
|
|
|
|
)
|
2018-10-15 16:46:42 -04:00
|
|
|
}).collect();
|
2018-10-03 17:56:56 -04:00
|
|
|
|
|
|
|
let entries = builder.create_vector(&entries);
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = msg::ReadDirRes::create(
|
2018-10-03 17:56:56 -04:00
|
|
|
builder,
|
|
|
|
&msg::ReadDirResArgs {
|
|
|
|
entries: Some(entries),
|
|
|
|
},
|
|
|
|
);
|
|
|
|
Ok(serialize_response(
|
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
2018-10-03 21:12:23 -04:00
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::ReadDirRes,
|
2018-10-03 17:56:56 -04:00
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_write_file(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-09-27 17:33:10 -04:00
|
|
|
) -> Box<Op> {
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = base.inner_as_write_file().unwrap();
|
|
|
|
let filename = String::from(inner.filename().unwrap());
|
2019-02-02 14:26:18 -05:00
|
|
|
let update_perm = inner.update_perm();
|
2018-10-03 21:12:23 -04:00
|
|
|
let perm = inner.perm();
|
2019-02-02 14:26:18 -05:00
|
|
|
let is_create = inner.is_create();
|
|
|
|
let is_append = inner.is_append();
|
2018-09-22 04:42:07 -04:00
|
|
|
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_write(&filename) {
|
2018-10-27 09:11:39 -04:00
|
|
|
return odd_future(e);
|
|
|
|
}
|
|
|
|
|
2018-12-11 08:36:34 -05:00
|
|
|
blocking(base.sync(), move || -> OpResult {
|
2018-10-03 20:48:02 -04:00
|
|
|
debug!("op_write_file {} {}", filename, data.len());
|
2019-02-02 14:26:18 -05:00
|
|
|
deno_fs::write_file_2(
|
|
|
|
Path::new(&filename),
|
|
|
|
data,
|
|
|
|
update_perm,
|
|
|
|
perm,
|
|
|
|
is_create,
|
|
|
|
is_append,
|
|
|
|
)?;
|
2018-09-18 14:53:16 -04:00
|
|
|
Ok(empty_buf())
|
2018-09-22 04:42:07 -04:00
|
|
|
})
|
2018-08-22 13:19:32 -04:00
|
|
|
}
|
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_rename(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-09-27 17:33:10 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = base.inner_as_rename().unwrap();
|
|
|
|
let oldpath = PathBuf::from(inner.oldpath().unwrap());
|
2018-10-27 09:11:39 -04:00
|
|
|
let newpath_ = inner.newpath().unwrap();
|
|
|
|
let newpath = PathBuf::from(newpath_);
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_write(&newpath_) {
|
2018-10-27 09:11:39 -04:00
|
|
|
return odd_future(e);
|
|
|
|
}
|
2018-12-11 08:36:34 -05:00
|
|
|
blocking(base.sync(), move || -> OpResult {
|
2018-10-03 20:48:02 -04:00
|
|
|
debug!("op_rename {} {}", oldpath.display(), newpath.display());
|
2018-09-22 04:42:07 -04:00
|
|
|
fs::rename(&oldpath, &newpath)?;
|
2018-09-18 14:53:16 -04:00
|
|
|
Ok(empty_buf())
|
2018-09-22 04:42:07 -04:00
|
|
|
})
|
2018-09-03 20:22:30 -04:00
|
|
|
}
|
2018-09-19 00:38:24 -04:00
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_symlink(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-09-27 17:33:10 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
2018-10-27 09:11:39 -04:00
|
|
|
let inner = base.inner_as_symlink().unwrap();
|
|
|
|
let oldname = PathBuf::from(inner.oldname().unwrap());
|
|
|
|
let newname_ = inner.newname().unwrap();
|
|
|
|
let newname = PathBuf::from(newname_);
|
|
|
|
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_write(&newname_) {
|
2018-10-27 09:11:39 -04:00
|
|
|
return odd_future(e);
|
2018-09-19 00:38:24 -04:00
|
|
|
}
|
|
|
|
// TODO Use type for Windows.
|
|
|
|
if cfg!(windows) {
|
2018-10-05 20:37:18 -04:00
|
|
|
return odd_future(errors::new(
|
|
|
|
ErrorKind::Other,
|
2018-10-05 21:35:29 -04:00
|
|
|
"Not implemented".to_string(),
|
2018-10-05 20:37:18 -04:00
|
|
|
));
|
2018-09-19 00:38:24 -04:00
|
|
|
}
|
2018-12-11 08:36:34 -05:00
|
|
|
blocking(base.sync(), move || -> OpResult {
|
2018-10-03 20:48:02 -04:00
|
|
|
debug!("op_symlink {} {}", oldname.display(), newname.display());
|
2018-09-22 04:42:07 -04:00
|
|
|
#[cfg(any(unix))]
|
|
|
|
std::os::unix::fs::symlink(&oldname, &newname)?;
|
|
|
|
Ok(empty_buf())
|
|
|
|
})
|
2018-09-19 00:38:24 -04:00
|
|
|
}
|
2018-09-25 00:20:49 -04:00
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_read_link(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-09-27 17:33:10 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = base.inner_as_readlink().unwrap();
|
2018-09-25 00:20:49 -04:00
|
|
|
let cmd_id = base.cmd_id();
|
2019-02-08 15:59:38 -05:00
|
|
|
let name_ = inner.name().unwrap();
|
|
|
|
let name = PathBuf::from(name_);
|
|
|
|
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_read(&name_) {
|
2019-02-08 15:59:38 -05:00
|
|
|
return odd_future(e);
|
|
|
|
}
|
2018-09-22 04:42:07 -04:00
|
|
|
|
2018-12-11 08:36:34 -05:00
|
|
|
blocking(base.sync(), move || -> OpResult {
|
2018-10-03 20:48:02 -04:00
|
|
|
debug!("op_read_link {}", name.display());
|
2018-09-22 04:42:07 -04:00
|
|
|
let path = fs::read_link(&name)?;
|
2018-09-25 00:20:49 -04:00
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
let path_off = builder.create_string(path.to_str().unwrap());
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = msg::ReadlinkRes::create(
|
2018-09-25 00:20:49 -04:00
|
|
|
builder,
|
|
|
|
&msg::ReadlinkResArgs {
|
|
|
|
path: Some(path_off),
|
|
|
|
},
|
|
|
|
);
|
|
|
|
Ok(serialize_response(
|
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
2018-10-03 21:12:23 -04:00
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::ReadlinkRes,
|
2018-09-25 00:20:49 -04:00
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
2018-09-22 04:42:07 -04:00
|
|
|
})
|
2018-09-25 00:20:49 -04:00
|
|
|
}
|
2018-09-30 15:06:20 -04:00
|
|
|
|
2018-11-05 12:55:59 -05:00
|
|
|
fn op_repl_start(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-11-05 12:55:59 -05:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
|
|
|
let inner = base.inner_as_repl_start().unwrap();
|
|
|
|
let cmd_id = base.cmd_id();
|
|
|
|
let history_file = String::from(inner.history_file().unwrap());
|
|
|
|
|
|
|
|
debug!("op_repl_start {}", history_file);
|
2019-03-01 19:25:50 -05:00
|
|
|
let history_path = repl::history_path(&isolate.state.dir, &history_file);
|
2018-11-05 12:55:59 -05:00
|
|
|
let repl = repl::Repl::new(history_path);
|
|
|
|
let resource = resources::add_repl(repl);
|
|
|
|
|
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
let inner = msg::ReplStartRes::create(
|
|
|
|
builder,
|
|
|
|
&msg::ReplStartResArgs { rid: resource.rid },
|
|
|
|
);
|
|
|
|
ok_future(serialize_response(
|
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::ReplStartRes,
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn op_repl_readline(
|
2019-03-01 19:25:50 -05:00
|
|
|
_isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-11-05 12:55:59 -05:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
|
|
|
let inner = base.inner_as_repl_readline().unwrap();
|
|
|
|
let cmd_id = base.cmd_id();
|
|
|
|
let rid = inner.rid();
|
|
|
|
let prompt = inner.prompt().unwrap().to_owned();
|
|
|
|
debug!("op_repl_readline {} {}", rid, prompt);
|
|
|
|
|
2018-12-11 08:36:34 -05:00
|
|
|
blocking(base.sync(), move || -> OpResult {
|
2019-02-09 16:55:40 -05:00
|
|
|
let repl = resources::get_repl(rid)?;
|
|
|
|
let line = repl.lock().unwrap().readline(&prompt)?;
|
2018-11-05 12:55:59 -05:00
|
|
|
|
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
let line_off = builder.create_string(&line);
|
|
|
|
let inner = msg::ReplReadlineRes::create(
|
|
|
|
builder,
|
|
|
|
&msg::ReplReadlineResArgs {
|
|
|
|
line: Some(line_off),
|
|
|
|
},
|
|
|
|
);
|
|
|
|
Ok(serialize_response(
|
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::ReplReadlineRes,
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
2018-11-28 04:07:22 -05:00
|
|
|
})
|
2018-11-05 12:55:59 -05:00
|
|
|
}
|
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_truncate(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-09-30 15:06:20 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
|
|
|
|
2018-10-03 21:12:23 -04:00
|
|
|
let inner = base.inner_as_truncate().unwrap();
|
|
|
|
let filename = String::from(inner.name().unwrap());
|
|
|
|
let len = inner.len();
|
2018-10-27 09:11:39 -04:00
|
|
|
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_write(&filename) {
|
2018-10-27 09:11:39 -04:00
|
|
|
return odd_future(e);
|
|
|
|
}
|
|
|
|
|
2018-12-11 08:36:34 -05:00
|
|
|
blocking(base.sync(), move || {
|
2018-10-03 20:48:02 -04:00
|
|
|
debug!("op_truncate {} {}", filename, len);
|
2018-09-30 15:06:20 -04:00
|
|
|
let f = fs::OpenOptions::new().write(true).open(&filename)?;
|
2018-11-04 09:04:24 -05:00
|
|
|
f.set_len(u64::from(len))?;
|
2018-09-30 15:06:20 -04:00
|
|
|
Ok(empty_buf())
|
|
|
|
})
|
|
|
|
}
|
2018-10-03 23:58:29 -04:00
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_listen(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-10-03 23:58:29 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_net("listen") {
|
2018-10-27 09:11:39 -04:00
|
|
|
return odd_future(e);
|
2018-10-03 23:58:29 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
let cmd_id = base.cmd_id();
|
2018-10-03 21:41:59 -04:00
|
|
|
let inner = base.inner_as_listen().unwrap();
|
|
|
|
let network = inner.network().unwrap();
|
2018-10-03 23:58:29 -04:00
|
|
|
assert_eq!(network, "tcp");
|
2018-10-03 21:41:59 -04:00
|
|
|
let address = inner.address().unwrap();
|
2018-10-03 23:58:29 -04:00
|
|
|
|
|
|
|
Box::new(futures::future::result((move || {
|
2019-01-13 22:14:59 -05:00
|
|
|
let addr = resolve_addr(address).wait()?;
|
2018-10-03 23:58:29 -04:00
|
|
|
|
|
|
|
let listener = TcpListener::bind(&addr)?;
|
|
|
|
let resource = resources::add_tcp_listener(listener);
|
|
|
|
|
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
2018-10-03 21:41:59 -04:00
|
|
|
let inner = msg::ListenRes::create(
|
2018-10-03 23:58:29 -04:00
|
|
|
builder,
|
2018-11-04 09:04:24 -05:00
|
|
|
&msg::ListenResArgs { rid: resource.rid },
|
2018-10-03 23:58:29 -04:00
|
|
|
);
|
|
|
|
Ok(serialize_response(
|
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
2018-10-03 21:41:59 -04:00
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::ListenRes,
|
2018-10-03 23:58:29 -04:00
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
})()))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn new_conn(cmd_id: u32, tcp_stream: TcpStream) -> OpResult {
|
|
|
|
let tcp_stream_resource = resources::add_tcp_stream(tcp_stream);
|
|
|
|
// TODO forward socket_addr to client.
|
|
|
|
|
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
2018-10-03 21:41:59 -04:00
|
|
|
let inner = msg::NewConn::create(
|
2018-10-03 23:58:29 -04:00
|
|
|
builder,
|
|
|
|
&msg::NewConnArgs {
|
|
|
|
rid: tcp_stream_resource.rid,
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
);
|
|
|
|
Ok(serialize_response(
|
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
2018-10-03 21:41:59 -04:00
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::NewConn,
|
2018-10-03 23:58:29 -04:00
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_accept(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-10-03 23:58:29 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_net("accept") {
|
2018-10-27 09:11:39 -04:00
|
|
|
return odd_future(e);
|
2018-10-03 23:58:29 -04:00
|
|
|
}
|
|
|
|
let cmd_id = base.cmd_id();
|
2018-10-03 21:41:59 -04:00
|
|
|
let inner = base.inner_as_accept().unwrap();
|
|
|
|
let server_rid = inner.rid();
|
2018-10-03 23:58:29 -04:00
|
|
|
|
|
|
|
match resources::lookup(server_rid) {
|
2018-10-05 10:20:51 -04:00
|
|
|
None => odd_future(errors::bad_resource()),
|
2018-10-03 23:58:29 -04:00
|
|
|
Some(server_resource) => {
|
2018-10-19 18:38:27 -04:00
|
|
|
let op = resources::eager_accept(server_resource)
|
2018-11-04 09:04:24 -05:00
|
|
|
.map_err(DenoError::from)
|
2018-10-03 23:58:29 -04:00
|
|
|
.and_then(move |(tcp_stream, _socket_addr)| {
|
|
|
|
new_conn(cmd_id, tcp_stream)
|
|
|
|
});
|
|
|
|
Box::new(op)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-03 20:48:02 -04:00
|
|
|
fn op_dial(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-10-03 23:58:29 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_net("dial") {
|
2018-10-27 09:11:39 -04:00
|
|
|
return odd_future(e);
|
2018-10-03 23:58:29 -04:00
|
|
|
}
|
|
|
|
let cmd_id = base.cmd_id();
|
2018-10-03 21:41:59 -04:00
|
|
|
let inner = base.inner_as_dial().unwrap();
|
|
|
|
let network = inner.network().unwrap();
|
2019-01-13 22:14:59 -05:00
|
|
|
assert_eq!(network, "tcp"); // TODO Support others.
|
2018-10-03 21:41:59 -04:00
|
|
|
let address = inner.address().unwrap();
|
2018-10-03 23:58:29 -04:00
|
|
|
|
2019-01-13 22:14:59 -05:00
|
|
|
let op =
|
|
|
|
resolve_addr(address)
|
|
|
|
.map_err(DenoError::from)
|
|
|
|
.and_then(move |addr| {
|
|
|
|
TcpStream::connect(&addr)
|
|
|
|
.map_err(DenoError::from)
|
|
|
|
.and_then(move |tcp_stream| new_conn(cmd_id, tcp_stream))
|
|
|
|
});
|
2018-10-03 23:58:29 -04:00
|
|
|
Box::new(op)
|
|
|
|
}
|
2018-10-05 13:21:15 -04:00
|
|
|
|
|
|
|
fn op_metrics(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-10-05 13:21:15 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
|
|
|
let cmd_id = base.cmd_id();
|
|
|
|
|
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
let inner = msg::MetricsRes::create(
|
|
|
|
builder,
|
2019-03-01 19:25:50 -05:00
|
|
|
&msg::MetricsResArgs::from(&isolate.state.metrics),
|
2018-10-05 13:21:15 -04:00
|
|
|
);
|
|
|
|
ok_future(serialize_response(
|
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::MetricsRes,
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|
2018-10-30 15:58:55 -04:00
|
|
|
|
|
|
|
fn op_resources(
|
2019-03-01 19:25:50 -05:00
|
|
|
_isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-10-30 15:58:55 -04:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
|
|
|
let cmd_id = base.cmd_id();
|
|
|
|
|
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
let serialized_resources = table_entries();
|
|
|
|
|
|
|
|
let res: Vec<_> = serialized_resources
|
|
|
|
.iter()
|
|
|
|
.map(|(key, value)| {
|
|
|
|
let repr = builder.create_string(value);
|
|
|
|
|
|
|
|
msg::Resource::create(
|
|
|
|
builder,
|
|
|
|
&msg::ResourceArgs {
|
2018-11-04 09:04:24 -05:00
|
|
|
rid: *key,
|
2018-10-30 15:58:55 -04:00
|
|
|
repr: Some(repr),
|
|
|
|
},
|
|
|
|
)
|
|
|
|
}).collect();
|
|
|
|
|
|
|
|
let resources = builder.create_vector(&res);
|
|
|
|
let inner = msg::ResourcesRes::create(
|
|
|
|
builder,
|
|
|
|
&msg::ResourcesResArgs {
|
|
|
|
resources: Some(resources),
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
ok_future(serialize_response(
|
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::ResourcesRes,
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|
2018-11-15 23:07:40 -05:00
|
|
|
|
|
|
|
fn subprocess_stdio_map(v: msg::ProcessStdio) -> std::process::Stdio {
|
|
|
|
match v {
|
|
|
|
msg::ProcessStdio::Inherit => std::process::Stdio::inherit(),
|
|
|
|
msg::ProcessStdio::Piped => std::process::Stdio::piped(),
|
|
|
|
msg::ProcessStdio::Null => std::process::Stdio::null(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn op_run(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-11-15 23:07:40 -05:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert!(base.sync());
|
|
|
|
let cmd_id = base.cmd_id();
|
|
|
|
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_run() {
|
2018-11-15 23:07:40 -05:00
|
|
|
return odd_future(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_eq!(data.len(), 0);
|
|
|
|
let inner = base.inner_as_run().unwrap();
|
|
|
|
let args = inner.args().unwrap();
|
2019-02-15 10:37:04 -05:00
|
|
|
let env = inner.env().unwrap();
|
2018-11-15 23:07:40 -05:00
|
|
|
let cwd = inner.cwd();
|
|
|
|
|
2018-11-30 03:30:49 -05:00
|
|
|
let mut c = Command::new(args.get(0));
|
2018-11-15 23:07:40 -05:00
|
|
|
(1..args.len()).for_each(|i| {
|
|
|
|
let arg = args.get(i);
|
2018-11-30 03:30:49 -05:00
|
|
|
c.arg(arg);
|
2018-11-15 23:07:40 -05:00
|
|
|
});
|
2018-11-30 03:30:49 -05:00
|
|
|
cwd.map(|d| c.current_dir(d));
|
2019-02-15 10:37:04 -05:00
|
|
|
(0..env.len()).for_each(|i| {
|
|
|
|
let entry = env.get(i);
|
|
|
|
c.env(entry.key().unwrap(), entry.value().unwrap());
|
|
|
|
});
|
2018-11-15 23:07:40 -05:00
|
|
|
|
2018-11-30 03:30:49 -05:00
|
|
|
c.stdin(subprocess_stdio_map(inner.stdin()));
|
|
|
|
c.stdout(subprocess_stdio_map(inner.stdout()));
|
|
|
|
c.stderr(subprocess_stdio_map(inner.stderr()));
|
2018-11-15 23:07:40 -05:00
|
|
|
|
|
|
|
// Spawn the command.
|
2018-11-30 03:30:49 -05:00
|
|
|
let child = match c.spawn_async() {
|
2018-11-15 23:07:40 -05:00
|
|
|
Ok(v) => v,
|
|
|
|
Err(err) => {
|
|
|
|
return odd_future(err.into());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
let pid = child.id();
|
|
|
|
let resources = resources::add_child(child);
|
|
|
|
|
|
|
|
let mut res_args = msg::RunResArgs {
|
|
|
|
rid: resources.child_rid,
|
|
|
|
pid,
|
|
|
|
..Default::default()
|
|
|
|
};
|
|
|
|
|
|
|
|
if let Some(stdin_rid) = resources.stdin_rid {
|
|
|
|
res_args.stdin_rid = stdin_rid;
|
|
|
|
}
|
|
|
|
if let Some(stdout_rid) = resources.stdout_rid {
|
|
|
|
res_args.stdout_rid = stdout_rid;
|
|
|
|
}
|
|
|
|
if let Some(stderr_rid) = resources.stderr_rid {
|
|
|
|
res_args.stderr_rid = stderr_rid;
|
|
|
|
}
|
|
|
|
|
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
let inner = msg::RunRes::create(builder, &res_args);
|
|
|
|
ok_future(serialize_response(
|
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::RunRes,
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn op_run_status(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2018-12-04 16:21:02 -05:00
|
|
|
data: libdeno::deno_buf,
|
2018-11-15 23:07:40 -05:00
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
|
|
|
let cmd_id = base.cmd_id();
|
|
|
|
let inner = base.inner_as_run_status().unwrap();
|
|
|
|
let rid = inner.rid();
|
|
|
|
|
2019-03-01 19:25:50 -05:00
|
|
|
if let Err(e) = isolate.check_run() {
|
2018-11-15 23:07:40 -05:00
|
|
|
return odd_future(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
let future = match resources::child_status(rid) {
|
|
|
|
Err(e) => {
|
|
|
|
return odd_future(e);
|
|
|
|
}
|
|
|
|
Ok(f) => f,
|
|
|
|
};
|
|
|
|
|
|
|
|
let future = future.and_then(move |run_status| {
|
|
|
|
let code = run_status.code();
|
|
|
|
|
|
|
|
#[cfg(unix)]
|
|
|
|
let signal = run_status.signal();
|
|
|
|
#[cfg(not(unix))]
|
|
|
|
let signal = None;
|
|
|
|
|
|
|
|
code
|
|
|
|
.or(signal)
|
|
|
|
.expect("Should have either an exit code or a signal.");
|
|
|
|
let got_signal = signal.is_some();
|
|
|
|
|
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
let inner = msg::RunStatusRes::create(
|
|
|
|
builder,
|
|
|
|
&msg::RunStatusResArgs {
|
|
|
|
got_signal,
|
|
|
|
exit_code: code.unwrap_or(-1),
|
|
|
|
exit_signal: signal.unwrap_or(-1),
|
|
|
|
},
|
|
|
|
);
|
|
|
|
Ok(serialize_response(
|
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::RunStatusRes,
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
});
|
|
|
|
Box::new(future)
|
|
|
|
}
|
2019-01-08 14:44:06 -05:00
|
|
|
|
|
|
|
struct GetMessageFuture {
|
|
|
|
pub state: Arc<IsolateState>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Future for GetMessageFuture {
|
|
|
|
type Item = Option<Buf>;
|
|
|
|
type Error = ();
|
|
|
|
|
|
|
|
fn poll(&mut self) -> Result<Async<Self::Item>, Self::Error> {
|
|
|
|
assert!(self.state.worker_channels.is_some());
|
|
|
|
match self.state.worker_channels {
|
|
|
|
None => panic!("expected worker_channels"),
|
|
|
|
Some(ref wc) => {
|
|
|
|
let mut wc = wc.lock().unwrap();
|
|
|
|
wc.1.poll()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn op_worker_get_message(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2019-01-08 14:44:06 -05:00
|
|
|
data: libdeno::deno_buf,
|
|
|
|
) -> Box<Op> {
|
|
|
|
assert_eq!(data.len(), 0);
|
|
|
|
let cmd_id = base.cmd_id();
|
|
|
|
|
|
|
|
let op = GetMessageFuture {
|
2019-03-01 19:25:50 -05:00
|
|
|
state: isolate.state.clone(),
|
2019-01-08 14:44:06 -05:00
|
|
|
};
|
|
|
|
let op = op.map_err(move |_| -> DenoError { unimplemented!() });
|
|
|
|
let op = op.and_then(move |maybe_buf| -> DenoResult<Buf> {
|
|
|
|
debug!("op_worker_get_message");
|
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
|
|
|
|
let data = maybe_buf.as_ref().map(|buf| builder.create_vector(buf));
|
|
|
|
let inner = msg::WorkerGetMessageRes::create(
|
|
|
|
builder,
|
|
|
|
&msg::WorkerGetMessageResArgs { data },
|
|
|
|
);
|
|
|
|
Ok(serialize_response(
|
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::WorkerGetMessageRes,
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
});
|
|
|
|
Box::new(op)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn op_worker_post_message(
|
2019-03-01 19:25:50 -05:00
|
|
|
isolate: &Isolate,
|
2019-01-14 01:30:38 -05:00
|
|
|
base: &msg::Base<'_>,
|
2019-01-08 14:44:06 -05:00
|
|
|
data: libdeno::deno_buf,
|
|
|
|
) -> Box<Op> {
|
|
|
|
let cmd_id = base.cmd_id();
|
|
|
|
|
|
|
|
let d = Vec::from(data.as_ref()).into_boxed_slice();
|
|
|
|
|
2019-03-01 19:25:50 -05:00
|
|
|
assert!(isolate.state.worker_channels.is_some());
|
|
|
|
let tx = match isolate.state.worker_channels {
|
2019-01-08 14:44:06 -05:00
|
|
|
None => panic!("expected worker_channels"),
|
|
|
|
Some(ref wc) => {
|
2019-01-14 01:30:38 -05:00
|
|
|
let wc = wc.lock().unwrap();
|
2019-01-08 14:44:06 -05:00
|
|
|
wc.0.clone()
|
|
|
|
}
|
|
|
|
};
|
|
|
|
let op = tx.send(d);
|
|
|
|
let op = op.map_err(|e| errors::new(ErrorKind::Other, e.to_string()));
|
|
|
|
let op = op.and_then(move |_| -> DenoResult<Buf> {
|
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
|
|
|
|
Ok(serialize_response(
|
|
|
|
cmd_id,
|
|
|
|
builder,
|
|
|
|
msg::BaseArgs {
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
))
|
|
|
|
});
|
|
|
|
Box::new(op)
|
|
|
|
}
|
2019-03-01 19:25:50 -05:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
use crate::isolate::{Isolate, IsolateState};
|
2019-03-04 18:09:35 -05:00
|
|
|
use crate::isolate_init::IsolateInit;
|
2019-03-01 19:25:50 -05:00
|
|
|
use crate::permissions::DenoPermissions;
|
|
|
|
use std::sync::atomic::AtomicBool;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn fetch_module_meta_fails_without_read() {
|
|
|
|
let state = IsolateState::mock();
|
|
|
|
let permissions = DenoPermissions {
|
|
|
|
allow_read: AtomicBool::new(false),
|
|
|
|
allow_write: AtomicBool::new(true),
|
|
|
|
allow_env: AtomicBool::new(true),
|
|
|
|
allow_net: AtomicBool::new(true),
|
|
|
|
allow_run: AtomicBool::new(true),
|
2019-03-13 12:43:47 -04:00
|
|
|
..Default::default()
|
2019-03-01 19:25:50 -05:00
|
|
|
};
|
2019-03-04 18:09:35 -05:00
|
|
|
let isolate = Isolate::new(
|
|
|
|
IsolateInit {
|
|
|
|
snapshot: None,
|
|
|
|
init_script: None,
|
|
|
|
},
|
|
|
|
state,
|
|
|
|
dispatch,
|
|
|
|
permissions,
|
|
|
|
);
|
2019-03-01 19:25:50 -05:00
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
let fetch_msg_args = msg::FetchModuleMetaDataArgs {
|
|
|
|
specifier: Some(builder.create_string("./somefile")),
|
|
|
|
referrer: Some(builder.create_string(".")),
|
|
|
|
};
|
|
|
|
let inner = msg::FetchModuleMetaData::create(builder, &fetch_msg_args);
|
|
|
|
let base_args = msg::BaseArgs {
|
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::FetchModuleMetaData,
|
|
|
|
..Default::default()
|
|
|
|
};
|
|
|
|
let base = msg::Base::create(builder, &base_args);
|
|
|
|
msg::finish_base_buffer(builder, base);
|
|
|
|
let data = builder.finished_data();
|
|
|
|
let final_msg = msg::get_root_as_base(&data);
|
|
|
|
let fetch_result = op_fetch_module_meta_data(
|
|
|
|
&isolate,
|
|
|
|
&final_msg,
|
|
|
|
libdeno::deno_buf::empty(),
|
|
|
|
).wait();
|
|
|
|
match fetch_result {
|
|
|
|
Ok(_) => assert!(true),
|
|
|
|
Err(e) => assert_eq!(e.to_string(), permission_denied().to_string()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-03 16:52:41 -05:00
|
|
|
#[test]
|
|
|
|
fn fetch_module_meta_fails_without_write() {
|
|
|
|
let state = IsolateState::mock();
|
|
|
|
let permissions = DenoPermissions {
|
|
|
|
allow_read: AtomicBool::new(true),
|
|
|
|
allow_write: AtomicBool::new(false),
|
|
|
|
allow_env: AtomicBool::new(true),
|
|
|
|
allow_net: AtomicBool::new(true),
|
|
|
|
allow_run: AtomicBool::new(true),
|
2019-03-13 12:43:47 -04:00
|
|
|
..Default::default()
|
2019-03-03 16:52:41 -05:00
|
|
|
};
|
2019-03-04 18:09:35 -05:00
|
|
|
let isolate = Isolate::new(
|
|
|
|
IsolateInit {
|
|
|
|
snapshot: None,
|
|
|
|
init_script: None,
|
|
|
|
},
|
|
|
|
state,
|
|
|
|
dispatch,
|
|
|
|
permissions,
|
|
|
|
);
|
2019-03-03 16:52:41 -05:00
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
let fetch_msg_args = msg::FetchModuleMetaDataArgs {
|
|
|
|
specifier: Some(builder.create_string("./somefile")),
|
|
|
|
referrer: Some(builder.create_string(".")),
|
|
|
|
};
|
|
|
|
let inner = msg::FetchModuleMetaData::create(builder, &fetch_msg_args);
|
|
|
|
let base_args = msg::BaseArgs {
|
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::FetchModuleMetaData,
|
|
|
|
..Default::default()
|
|
|
|
};
|
|
|
|
let base = msg::Base::create(builder, &base_args);
|
|
|
|
msg::finish_base_buffer(builder, base);
|
|
|
|
let data = builder.finished_data();
|
|
|
|
let final_msg = msg::get_root_as_base(&data);
|
|
|
|
let fetch_result = op_fetch_module_meta_data(
|
|
|
|
&isolate,
|
|
|
|
&final_msg,
|
|
|
|
libdeno::deno_buf::empty(),
|
|
|
|
).wait();
|
|
|
|
match fetch_result {
|
|
|
|
Ok(_) => assert!(true),
|
|
|
|
Err(e) => assert_eq!(e.to_string(), permission_denied().to_string()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-01 19:25:50 -05:00
|
|
|
#[test]
|
|
|
|
fn fetch_module_meta_fails_without_net() {
|
|
|
|
let state = IsolateState::mock();
|
|
|
|
let permissions = DenoPermissions {
|
|
|
|
allow_read: AtomicBool::new(true),
|
|
|
|
allow_write: AtomicBool::new(true),
|
|
|
|
allow_env: AtomicBool::new(true),
|
|
|
|
allow_net: AtomicBool::new(false),
|
|
|
|
allow_run: AtomicBool::new(true),
|
2019-03-13 12:43:47 -04:00
|
|
|
..Default::default()
|
2019-03-01 19:25:50 -05:00
|
|
|
};
|
2019-03-04 18:09:35 -05:00
|
|
|
let isolate = Isolate::new(
|
|
|
|
IsolateInit {
|
|
|
|
snapshot: None,
|
|
|
|
init_script: None,
|
|
|
|
},
|
|
|
|
state,
|
|
|
|
dispatch,
|
|
|
|
permissions,
|
|
|
|
);
|
2019-03-01 19:25:50 -05:00
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
let fetch_msg_args = msg::FetchModuleMetaDataArgs {
|
|
|
|
specifier: Some(builder.create_string("./somefile")),
|
|
|
|
referrer: Some(builder.create_string(".")),
|
|
|
|
};
|
|
|
|
let inner = msg::FetchModuleMetaData::create(builder, &fetch_msg_args);
|
|
|
|
let base_args = msg::BaseArgs {
|
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::FetchModuleMetaData,
|
|
|
|
..Default::default()
|
|
|
|
};
|
|
|
|
let base = msg::Base::create(builder, &base_args);
|
|
|
|
msg::finish_base_buffer(builder, base);
|
|
|
|
let data = builder.finished_data();
|
|
|
|
let final_msg = msg::get_root_as_base(&data);
|
|
|
|
let fetch_result = op_fetch_module_meta_data(
|
|
|
|
&isolate,
|
|
|
|
&final_msg,
|
|
|
|
libdeno::deno_buf::empty(),
|
|
|
|
).wait();
|
|
|
|
match fetch_result {
|
|
|
|
Ok(_) => assert!(true),
|
|
|
|
Err(e) => assert_eq!(e.to_string(), permission_denied().to_string()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn fetch_module_meta_not_permission_denied_with_permissions() {
|
|
|
|
let state = IsolateState::mock();
|
|
|
|
let permissions = DenoPermissions {
|
|
|
|
allow_read: AtomicBool::new(true),
|
2019-03-03 16:52:41 -05:00
|
|
|
allow_write: AtomicBool::new(true),
|
2019-03-01 19:25:50 -05:00
|
|
|
allow_env: AtomicBool::new(false),
|
|
|
|
allow_net: AtomicBool::new(true),
|
|
|
|
allow_run: AtomicBool::new(false),
|
2019-03-13 12:43:47 -04:00
|
|
|
..Default::default()
|
2019-03-01 19:25:50 -05:00
|
|
|
};
|
2019-03-04 18:09:35 -05:00
|
|
|
let isolate = Isolate::new(
|
|
|
|
IsolateInit {
|
|
|
|
snapshot: None,
|
|
|
|
init_script: None,
|
|
|
|
},
|
|
|
|
state,
|
|
|
|
dispatch,
|
|
|
|
permissions,
|
|
|
|
);
|
2019-03-01 19:25:50 -05:00
|
|
|
let builder = &mut FlatBufferBuilder::new();
|
|
|
|
let fetch_msg_args = msg::FetchModuleMetaDataArgs {
|
|
|
|
specifier: Some(builder.create_string("./somefile")),
|
|
|
|
referrer: Some(builder.create_string(".")),
|
|
|
|
};
|
|
|
|
let inner = msg::FetchModuleMetaData::create(builder, &fetch_msg_args);
|
|
|
|
let base_args = msg::BaseArgs {
|
|
|
|
inner: Some(inner.as_union_value()),
|
|
|
|
inner_type: msg::Any::FetchModuleMetaData,
|
|
|
|
..Default::default()
|
|
|
|
};
|
|
|
|
let base = msg::Base::create(builder, &base_args);
|
|
|
|
msg::finish_base_buffer(builder, base);
|
|
|
|
let data = builder.finished_data();
|
|
|
|
let final_msg = msg::get_root_as_base(&data);
|
|
|
|
let fetch_result = op_fetch_module_meta_data(
|
|
|
|
&isolate,
|
|
|
|
&final_msg,
|
|
|
|
libdeno::deno_buf::empty(),
|
|
|
|
).wait();
|
|
|
|
match fetch_result {
|
|
|
|
Ok(_) => assert!(true),
|
|
|
|
Err(e) => assert!(e.to_string() != permission_denied().to_string()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|