mirror of
https://github.com/denoland/deno.git
synced 2025-01-12 09:03:42 -05:00
port fs ops to JSON (#2812)
This commit is contained in:
parent
520f9631e0
commit
a6f6209f52
21 changed files with 480 additions and 637 deletions
114
cli/msg.fbs
114
cli/msg.fbs
|
@ -1,27 +1,7 @@
|
||||||
union Any {
|
union Any {
|
||||||
Chdir,
|
|
||||||
Chmod,
|
|
||||||
Chown,
|
|
||||||
CopyFile,
|
|
||||||
Cwd,
|
|
||||||
CwdRes,
|
|
||||||
Link,
|
|
||||||
MakeTempDir,
|
|
||||||
MakeTempDirRes,
|
|
||||||
Mkdir,
|
|
||||||
Read,
|
Read,
|
||||||
ReadDir,
|
|
||||||
ReadDirRes,
|
|
||||||
ReadRes,
|
ReadRes,
|
||||||
Readlink,
|
|
||||||
ReadlinkRes,
|
|
||||||
Remove,
|
|
||||||
Rename,
|
|
||||||
Seek,
|
Seek,
|
||||||
Stat,
|
|
||||||
StatRes,
|
|
||||||
Symlink,
|
|
||||||
Truncate,
|
|
||||||
Write,
|
Write,
|
||||||
WriteRes,
|
WriteRes,
|
||||||
}
|
}
|
||||||
|
@ -122,105 +102,11 @@ table FormatErrorRes {
|
||||||
error: string;
|
error: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
table Chdir {
|
|
||||||
directory: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
table KeyValue {
|
table KeyValue {
|
||||||
key: string;
|
key: string;
|
||||||
value: string;
|
value: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
table MakeTempDir {
|
|
||||||
dir: string;
|
|
||||||
prefix: string;
|
|
||||||
suffix: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
table MakeTempDirRes {
|
|
||||||
path: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
table Mkdir {
|
|
||||||
path: string;
|
|
||||||
recursive: bool;
|
|
||||||
mode: uint; // Specified by https://godoc.org/os#FileMode
|
|
||||||
}
|
|
||||||
|
|
||||||
table Chmod {
|
|
||||||
path: string;
|
|
||||||
mode: uint; // Specified by https://godoc.org/os#FileMode
|
|
||||||
}
|
|
||||||
|
|
||||||
table Chown {
|
|
||||||
path: string;
|
|
||||||
uid: uint;
|
|
||||||
gid: uint; // Specified by https://godoc.org/os#Chown
|
|
||||||
}
|
|
||||||
|
|
||||||
table Remove {
|
|
||||||
path: string;
|
|
||||||
recursive: bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
table ReadDir {
|
|
||||||
path: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
table ReadDirRes {
|
|
||||||
entries: [StatRes];
|
|
||||||
}
|
|
||||||
|
|
||||||
table CopyFile {
|
|
||||||
from: string;
|
|
||||||
to: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
table Rename {
|
|
||||||
oldpath: string;
|
|
||||||
newpath: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
table Readlink {
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
table ReadlinkRes {
|
|
||||||
path: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
table Symlink {
|
|
||||||
oldname: string;
|
|
||||||
newname: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
table Link {
|
|
||||||
oldname: string;
|
|
||||||
newname: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
table Stat {
|
|
||||||
filename: string;
|
|
||||||
lstat: bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
table StatRes {
|
|
||||||
is_file: bool;
|
|
||||||
is_symlink: bool;
|
|
||||||
len: ulong;
|
|
||||||
modified:ulong;
|
|
||||||
accessed:ulong;
|
|
||||||
created:ulong;
|
|
||||||
mode: uint;
|
|
||||||
has_mode: bool; // false on windows
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
table Truncate {
|
|
||||||
name: string;
|
|
||||||
len: uint;
|
|
||||||
}
|
|
||||||
|
|
||||||
table Read {
|
table Read {
|
||||||
rid: uint32;
|
rid: uint32;
|
||||||
// (ptr, len) is passed as second parameter to Deno.core.send().
|
// (ptr, len) is passed as second parameter to Deno.core.send().
|
||||||
|
|
|
@ -6,19 +6,14 @@ use deno::*;
|
||||||
use flatbuffers::FlatBufferBuilder;
|
use flatbuffers::FlatBufferBuilder;
|
||||||
use hyper::rt::Future;
|
use hyper::rt::Future;
|
||||||
|
|
||||||
use super::files::{op_read, op_write};
|
|
||||||
use super::fs::{
|
|
||||||
op_chdir, op_chmod, op_chown, op_copy_file, op_cwd, op_link,
|
|
||||||
op_make_temp_dir, op_mkdir, op_read_dir, op_read_link, op_remove, op_rename,
|
|
||||||
op_stat, op_symlink, op_truncate,
|
|
||||||
};
|
|
||||||
|
|
||||||
type CliDispatchFn = fn(
|
type CliDispatchFn = fn(
|
||||||
state: &ThreadSafeState,
|
state: &ThreadSafeState,
|
||||||
base: &msg::Base<'_>,
|
base: &msg::Base<'_>,
|
||||||
data: Option<PinnedBuf>,
|
data: Option<PinnedBuf>,
|
||||||
) -> CliOpResult;
|
) -> CliOpResult;
|
||||||
|
|
||||||
|
use super::files::{op_read, op_write};
|
||||||
|
|
||||||
/// Processes raw messages from JavaScript.
|
/// Processes raw messages from JavaScript.
|
||||||
/// This functions invoked every time Deno.core.dispatch() is called.
|
/// This functions invoked every time Deno.core.dispatch() is called.
|
||||||
/// control corresponds to the first argument of Deno.core.dispatch().
|
/// control corresponds to the first argument of Deno.core.dispatch().
|
||||||
|
@ -125,22 +120,7 @@ pub fn serialize_response(
|
||||||
/// Standard ops set for most isolates
|
/// Standard ops set for most isolates
|
||||||
pub fn op_selector_std(inner_type: msg::Any) -> Option<CliDispatchFn> {
|
pub fn op_selector_std(inner_type: msg::Any) -> Option<CliDispatchFn> {
|
||||||
match inner_type {
|
match inner_type {
|
||||||
msg::Any::Chdir => Some(op_chdir),
|
|
||||||
msg::Any::Chmod => Some(op_chmod),
|
|
||||||
msg::Any::Chown => Some(op_chown),
|
|
||||||
msg::Any::CopyFile => Some(op_copy_file),
|
|
||||||
msg::Any::Cwd => Some(op_cwd),
|
|
||||||
msg::Any::Link => Some(op_link),
|
|
||||||
msg::Any::MakeTempDir => Some(op_make_temp_dir),
|
|
||||||
msg::Any::Mkdir => Some(op_mkdir),
|
|
||||||
msg::Any::Read => Some(op_read),
|
msg::Any::Read => Some(op_read),
|
||||||
msg::Any::ReadDir => Some(op_read_dir),
|
|
||||||
msg::Any::Readlink => Some(op_read_link),
|
|
||||||
msg::Any::Remove => Some(op_remove),
|
|
||||||
msg::Any::Rename => Some(op_rename),
|
|
||||||
msg::Any::Stat => Some(op_stat),
|
|
||||||
msg::Any::Symlink => Some(op_symlink),
|
|
||||||
msg::Any::Truncate => Some(op_truncate),
|
|
||||||
msg::Any::Write => Some(op_write),
|
msg::Any::Write => Some(op_write),
|
||||||
|
|
||||||
_ => None,
|
_ => None,
|
||||||
|
|
526
cli/ops/fs.rs
526
cli/ops/fs.rs
|
@ -1,14 +1,12 @@
|
||||||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||||
use super::dispatch_flatbuffers::serialize_response;
|
// Some deserializer fields are only used on Unix and Windows build fails without it
|
||||||
|
#![allow(dead_code)]
|
||||||
use super::dispatch_json::{blocking_json, Deserialize, JsonOp, Value};
|
use super::dispatch_json::{blocking_json, Deserialize, JsonOp, Value};
|
||||||
use super::utils::*;
|
|
||||||
use crate::deno_error::DenoError;
|
use crate::deno_error::DenoError;
|
||||||
use crate::deno_error::ErrorKind;
|
use crate::deno_error::ErrorKind;
|
||||||
use crate::fs as deno_fs;
|
use crate::fs as deno_fs;
|
||||||
use crate::msg;
|
|
||||||
use crate::state::ThreadSafeState;
|
use crate::state::ThreadSafeState;
|
||||||
use deno::*;
|
use deno::*;
|
||||||
use flatbuffers::FlatBufferBuilder;
|
|
||||||
use remove_dir_all::remove_dir_all;
|
use remove_dir_all::remove_dir_all;
|
||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
@ -18,99 +16,130 @@ use std::time::UNIX_EPOCH;
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use std::os::unix::fs::PermissionsExt;
|
use std::os::unix::fs::PermissionsExt;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct ChdirArgs {
|
||||||
|
directory: String,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn op_chdir(
|
pub fn op_chdir(
|
||||||
_state: &ThreadSafeState,
|
_state: &ThreadSafeState,
|
||||||
base: &msg::Base<'_>,
|
args: Value,
|
||||||
data: Option<PinnedBuf>,
|
_zero_copy: Option<PinnedBuf>,
|
||||||
) -> CliOpResult {
|
) -> Result<JsonOp, ErrBox> {
|
||||||
assert!(data.is_none());
|
let args: ChdirArgs = serde_json::from_value(args)?;
|
||||||
let inner = base.inner_as_chdir().unwrap();
|
std::env::set_current_dir(&args.directory)?;
|
||||||
let directory = inner.directory().unwrap();
|
Ok(JsonOp::Sync(json!({})))
|
||||||
std::env::set_current_dir(&directory)?;
|
}
|
||||||
ok_buf(empty_buf())
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct MkdirArgs {
|
||||||
|
promise_id: Option<u64>,
|
||||||
|
path: String,
|
||||||
|
recursive: bool,
|
||||||
|
mode: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn op_mkdir(
|
pub fn op_mkdir(
|
||||||
state: &ThreadSafeState,
|
state: &ThreadSafeState,
|
||||||
base: &msg::Base<'_>,
|
args: Value,
|
||||||
data: Option<PinnedBuf>,
|
_zero_copy: Option<PinnedBuf>,
|
||||||
) -> CliOpResult {
|
) -> Result<JsonOp, ErrBox> {
|
||||||
assert!(data.is_none());
|
let args: MkdirArgs = serde_json::from_value(args)?;
|
||||||
let inner = base.inner_as_mkdir().unwrap();
|
let (path, path_) = deno_fs::resolve_from_cwd(args.path.as_ref())?;
|
||||||
let (path, path_) = deno_fs::resolve_from_cwd(inner.path().unwrap())?;
|
|
||||||
let recursive = inner.recursive();
|
|
||||||
let mode = inner.mode();
|
|
||||||
|
|
||||||
state.check_write(&path_)?;
|
state.check_write(&path_)?;
|
||||||
|
|
||||||
blocking(base.sync(), move || {
|
let is_sync = args.promise_id.is_none();
|
||||||
|
blocking_json(is_sync, move || {
|
||||||
debug!("op_mkdir {}", path_);
|
debug!("op_mkdir {}", path_);
|
||||||
deno_fs::mkdir(&path, mode, recursive)?;
|
deno_fs::mkdir(&path, args.mode, args.recursive)?;
|
||||||
Ok(empty_buf())
|
Ok(json!({}))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct ChmodArgs {
|
||||||
|
promise_id: Option<u64>,
|
||||||
|
path: String,
|
||||||
|
mode: u32,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn op_chmod(
|
pub fn op_chmod(
|
||||||
state: &ThreadSafeState,
|
state: &ThreadSafeState,
|
||||||
base: &msg::Base<'_>,
|
args: Value,
|
||||||
data: Option<PinnedBuf>,
|
_zero_copy: Option<PinnedBuf>,
|
||||||
) -> CliOpResult {
|
) -> Result<JsonOp, ErrBox> {
|
||||||
assert!(data.is_none());
|
let args: ChmodArgs = serde_json::from_value(args)?;
|
||||||
let inner = base.inner_as_chmod().unwrap();
|
let (path, path_) = deno_fs::resolve_from_cwd(args.path.as_ref())?;
|
||||||
let _mode = inner.mode();
|
|
||||||
let (path, path_) = deno_fs::resolve_from_cwd(inner.path().unwrap())?;
|
|
||||||
|
|
||||||
state.check_write(&path_)?;
|
state.check_write(&path_)?;
|
||||||
|
|
||||||
blocking(base.sync(), move || {
|
let is_sync = args.promise_id.is_none();
|
||||||
|
blocking_json(is_sync, move || {
|
||||||
debug!("op_chmod {}", &path_);
|
debug!("op_chmod {}", &path_);
|
||||||
// Still check file/dir exists on windows
|
// Still check file/dir exists on windows
|
||||||
let _metadata = fs::metadata(&path)?;
|
let _metadata = fs::metadata(&path)?;
|
||||||
#[cfg(any(unix))]
|
#[cfg(any(unix))]
|
||||||
{
|
{
|
||||||
let mut permissions = _metadata.permissions();
|
let mut permissions = _metadata.permissions();
|
||||||
permissions.set_mode(_mode);
|
permissions.set_mode(args.mode);
|
||||||
fs::set_permissions(&path, permissions)?;
|
fs::set_permissions(&path, permissions)?;
|
||||||
}
|
}
|
||||||
Ok(empty_buf())
|
Ok(json!({}))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct ChownArgs {
|
||||||
|
promise_id: Option<u64>,
|
||||||
|
path: String,
|
||||||
|
uid: u32,
|
||||||
|
gid: u32,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn op_chown(
|
pub fn op_chown(
|
||||||
state: &ThreadSafeState,
|
state: &ThreadSafeState,
|
||||||
base: &msg::Base<'_>,
|
args: Value,
|
||||||
data: Option<PinnedBuf>,
|
_zero_copy: Option<PinnedBuf>,
|
||||||
) -> CliOpResult {
|
) -> Result<JsonOp, ErrBox> {
|
||||||
assert!(data.is_none());
|
let args: ChownArgs = serde_json::from_value(args)?;
|
||||||
let inner = base.inner_as_chown().unwrap();
|
|
||||||
let path = String::from(inner.path().unwrap());
|
|
||||||
let uid = inner.uid();
|
|
||||||
let gid = inner.gid();
|
|
||||||
|
|
||||||
state.check_write(&path)?;
|
state.check_write(&args.path)?;
|
||||||
|
|
||||||
blocking(base.sync(), move || {
|
let is_sync = args.promise_id.is_none();
|
||||||
debug!("op_chown {}", &path);
|
blocking_json(is_sync, move || {
|
||||||
match deno_fs::chown(&path, uid, gid) {
|
debug!("op_chown {}", &args.path);
|
||||||
Ok(_) => Ok(empty_buf()),
|
match deno_fs::chown(args.path.as_ref(), args.uid, args.gid) {
|
||||||
|
Ok(_) => Ok(json!({})),
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct RemoveArgs {
|
||||||
|
promise_id: Option<u64>,
|
||||||
|
path: String,
|
||||||
|
recursive: bool,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn op_remove(
|
pub fn op_remove(
|
||||||
state: &ThreadSafeState,
|
state: &ThreadSafeState,
|
||||||
base: &msg::Base<'_>,
|
args: Value,
|
||||||
data: Option<PinnedBuf>,
|
_zero_copy: Option<PinnedBuf>,
|
||||||
) -> CliOpResult {
|
) -> Result<JsonOp, ErrBox> {
|
||||||
assert!(data.is_none());
|
let args: RemoveArgs = serde_json::from_value(args)?;
|
||||||
let inner = base.inner_as_remove().unwrap();
|
let (path, path_) = deno_fs::resolve_from_cwd(args.path.as_ref())?;
|
||||||
let (path, path_) = deno_fs::resolve_from_cwd(inner.path().unwrap())?;
|
let recursive = args.recursive;
|
||||||
let recursive = inner.recursive();
|
|
||||||
|
|
||||||
state.check_write(&path_)?;
|
state.check_write(&path_)?;
|
||||||
|
|
||||||
blocking(base.sync(), move || {
|
let is_sync = args.promise_id.is_none();
|
||||||
|
blocking_json(is_sync, move || {
|
||||||
debug!("op_remove {}", path.display());
|
debug!("op_remove {}", path.display());
|
||||||
let metadata = fs::metadata(&path)?;
|
let metadata = fs::metadata(&path)?;
|
||||||
if metadata.is_file() {
|
if metadata.is_file() {
|
||||||
|
@ -120,25 +149,34 @@ pub fn op_remove(
|
||||||
} else {
|
} else {
|
||||||
fs::remove_dir(&path)?;
|
fs::remove_dir(&path)?;
|
||||||
}
|
}
|
||||||
Ok(empty_buf())
|
Ok(json!({}))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct CopyFileArgs {
|
||||||
|
promise_id: Option<u64>,
|
||||||
|
from: String,
|
||||||
|
to: String,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn op_copy_file(
|
pub fn op_copy_file(
|
||||||
state: &ThreadSafeState,
|
state: &ThreadSafeState,
|
||||||
base: &msg::Base<'_>,
|
args: Value,
|
||||||
data: Option<PinnedBuf>,
|
_zero_copy: Option<PinnedBuf>,
|
||||||
) -> CliOpResult {
|
) -> Result<JsonOp, ErrBox> {
|
||||||
assert!(data.is_none());
|
let args: CopyFileArgs = serde_json::from_value(args)?;
|
||||||
let inner = base.inner_as_copy_file().unwrap();
|
|
||||||
let (from, from_) = deno_fs::resolve_from_cwd(inner.from().unwrap())?;
|
let (from, from_) = deno_fs::resolve_from_cwd(args.from.as_ref())?;
|
||||||
let (to, to_) = deno_fs::resolve_from_cwd(inner.to().unwrap())?;
|
let (to, to_) = deno_fs::resolve_from_cwd(args.to.as_ref())?;
|
||||||
|
|
||||||
state.check_read(&from_)?;
|
state.check_read(&from_)?;
|
||||||
state.check_write(&to_)?;
|
state.check_write(&to_)?;
|
||||||
|
|
||||||
debug!("op_copy_file {} {}", from.display(), to.display());
|
debug!("op_copy_file {} {}", from.display(), to.display());
|
||||||
blocking(base.sync(), move || {
|
let is_sync = args.promise_id.is_none();
|
||||||
|
blocking_json(is_sync, move || {
|
||||||
// On *nix, Rust deem non-existent path as invalid input
|
// On *nix, Rust deem non-existent path as invalid input
|
||||||
// See https://github.com/rust-lang/rust/issues/54800
|
// See https://github.com/rust-lang/rust/issues/54800
|
||||||
// Once the issue is reolved, we should remove this workaround.
|
// Once the issue is reolved, we should remove this workaround.
|
||||||
|
@ -150,7 +188,7 @@ pub fn op_copy_file(
|
||||||
}
|
}
|
||||||
|
|
||||||
fs::copy(&from, &to)?;
|
fs::copy(&from, &to)?;
|
||||||
Ok(empty_buf())
|
Ok(json!({}))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,22 +212,29 @@ fn get_mode(_perm: &fs::Permissions) -> u32 {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct StatArgs {
|
||||||
|
promise_id: Option<u64>,
|
||||||
|
filename: String,
|
||||||
|
lstat: bool,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn op_stat(
|
pub fn op_stat(
|
||||||
state: &ThreadSafeState,
|
state: &ThreadSafeState,
|
||||||
base: &msg::Base<'_>,
|
args: Value,
|
||||||
data: Option<PinnedBuf>,
|
_zero_copy: Option<PinnedBuf>,
|
||||||
) -> CliOpResult {
|
) -> Result<JsonOp, ErrBox> {
|
||||||
assert!(data.is_none());
|
let args: StatArgs = serde_json::from_value(args)?;
|
||||||
let inner = base.inner_as_stat().unwrap();
|
|
||||||
let cmd_id = base.cmd_id();
|
|
||||||
let (filename, filename_) =
|
let (filename, filename_) =
|
||||||
deno_fs::resolve_from_cwd(inner.filename().unwrap())?;
|
deno_fs::resolve_from_cwd(args.filename.as_ref())?;
|
||||||
let lstat = inner.lstat();
|
let lstat = args.lstat;
|
||||||
|
|
||||||
state.check_read(&filename_)?;
|
state.check_read(&filename_)?;
|
||||||
|
|
||||||
blocking(base.sync(), move || {
|
let is_sync = args.promise_id.is_none();
|
||||||
let builder = &mut FlatBufferBuilder::new();
|
blocking_json(is_sync, move || {
|
||||||
debug!("op_stat {} {}", filename.display(), lstat);
|
debug!("op_stat {} {}", filename.display(), lstat);
|
||||||
let metadata = if lstat {
|
let metadata = if lstat {
|
||||||
fs::symlink_metadata(&filename)?
|
fs::symlink_metadata(&filename)?
|
||||||
|
@ -197,146 +242,140 @@ pub fn op_stat(
|
||||||
fs::metadata(&filename)?
|
fs::metadata(&filename)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let inner = msg::StatRes::create(
|
Ok(json!({
|
||||||
builder,
|
"isFile": metadata.is_file(),
|
||||||
&msg::StatResArgs {
|
"isSymlink": metadata.file_type().is_symlink(),
|
||||||
is_file: metadata.is_file(),
|
"len": metadata.len(),
|
||||||
is_symlink: metadata.file_type().is_symlink(),
|
"modified":to_seconds!(metadata.modified()),
|
||||||
len: metadata.len(),
|
"accessed":to_seconds!(metadata.accessed()),
|
||||||
modified: to_seconds!(metadata.modified()),
|
"created":to_seconds!(metadata.created()),
|
||||||
accessed: to_seconds!(metadata.accessed()),
|
"mode": get_mode(&metadata.permissions()),
|
||||||
created: to_seconds!(metadata.created()),
|
"hasMode": cfg!(target_family = "unix"), // false on windows,
|
||||||
mode: get_mode(&metadata.permissions()),
|
}))
|
||||||
has_mode: cfg!(target_family = "unix"),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(serialize_response(
|
|
||||||
cmd_id,
|
|
||||||
builder,
|
|
||||||
msg::BaseArgs {
|
|
||||||
inner: Some(inner.as_union_value()),
|
|
||||||
inner_type: msg::Any::StatRes,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct ReadDirArgs {
|
||||||
|
promise_id: Option<u64>,
|
||||||
|
path: String,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn op_read_dir(
|
pub fn op_read_dir(
|
||||||
state: &ThreadSafeState,
|
state: &ThreadSafeState,
|
||||||
base: &msg::Base<'_>,
|
args: Value,
|
||||||
data: Option<PinnedBuf>,
|
_zero_copy: Option<PinnedBuf>,
|
||||||
) -> CliOpResult {
|
) -> Result<JsonOp, ErrBox> {
|
||||||
assert!(data.is_none());
|
let args: ReadDirArgs = serde_json::from_value(args)?;
|
||||||
let inner = base.inner_as_read_dir().unwrap();
|
let (path, path_) = deno_fs::resolve_from_cwd(args.path.as_ref())?;
|
||||||
let cmd_id = base.cmd_id();
|
|
||||||
let (path, path_) = deno_fs::resolve_from_cwd(inner.path().unwrap())?;
|
|
||||||
|
|
||||||
state.check_read(&path_)?;
|
state.check_read(&path_)?;
|
||||||
|
|
||||||
blocking(base.sync(), move || {
|
let is_sync = args.promise_id.is_none();
|
||||||
|
blocking_json(is_sync, move || {
|
||||||
debug!("op_read_dir {}", path.display());
|
debug!("op_read_dir {}", path.display());
|
||||||
let builder = &mut FlatBufferBuilder::new();
|
|
||||||
let entries: Vec<_> = fs::read_dir(path)?
|
let entries: Vec<_> = fs::read_dir(path)?
|
||||||
.map(|entry| {
|
.map(|entry| {
|
||||||
let entry = entry.unwrap();
|
let entry = entry.unwrap();
|
||||||
let metadata = entry.metadata().unwrap();
|
let metadata = entry.metadata().unwrap();
|
||||||
let file_type = metadata.file_type();
|
let file_type = metadata.file_type();
|
||||||
let name = builder.create_string(entry.file_name().to_str().unwrap());
|
|
||||||
|
|
||||||
msg::StatRes::create(
|
json!({
|
||||||
builder,
|
"isFile": file_type.is_file(),
|
||||||
&msg::StatResArgs {
|
"isSymlink": file_type.is_symlink(),
|
||||||
is_file: file_type.is_file(),
|
"len": metadata.len(),
|
||||||
is_symlink: file_type.is_symlink(),
|
"modified": to_seconds!(metadata.modified()),
|
||||||
len: metadata.len(),
|
"accessed": to_seconds!(metadata.accessed()),
|
||||||
modified: to_seconds!(metadata.modified()),
|
"created": to_seconds!(metadata.created()),
|
||||||
accessed: to_seconds!(metadata.accessed()),
|
"mode": get_mode(&metadata.permissions()),
|
||||||
created: to_seconds!(metadata.created()),
|
"name": entry.file_name().to_str().unwrap(),
|
||||||
name: Some(name),
|
"hasMode": cfg!(target_family = "unix"), // false on windows,
|
||||||
mode: get_mode(&metadata.permissions()),
|
})
|
||||||
has_mode: cfg!(target_family = "unix"),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let entries = builder.create_vector(&entries);
|
Ok(json!({ "entries": entries }))
|
||||||
let inner = msg::ReadDirRes::create(
|
|
||||||
builder,
|
|
||||||
&msg::ReadDirResArgs {
|
|
||||||
entries: Some(entries),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
Ok(serialize_response(
|
|
||||||
cmd_id,
|
|
||||||
builder,
|
|
||||||
msg::BaseArgs {
|
|
||||||
inner: Some(inner.as_union_value()),
|
|
||||||
inner_type: msg::Any::ReadDirRes,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct RenameArgs {
|
||||||
|
promise_id: Option<u64>,
|
||||||
|
oldpath: String,
|
||||||
|
newpath: String,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn op_rename(
|
pub fn op_rename(
|
||||||
state: &ThreadSafeState,
|
state: &ThreadSafeState,
|
||||||
base: &msg::Base<'_>,
|
args: Value,
|
||||||
data: Option<PinnedBuf>,
|
_zero_copy: Option<PinnedBuf>,
|
||||||
) -> CliOpResult {
|
) -> Result<JsonOp, ErrBox> {
|
||||||
assert!(data.is_none());
|
let args: RenameArgs = serde_json::from_value(args)?;
|
||||||
let inner = base.inner_as_rename().unwrap();
|
|
||||||
let (oldpath, oldpath_) =
|
let (oldpath, oldpath_) = deno_fs::resolve_from_cwd(args.oldpath.as_ref())?;
|
||||||
deno_fs::resolve_from_cwd(inner.oldpath().unwrap())?;
|
let (newpath, newpath_) = deno_fs::resolve_from_cwd(args.newpath.as_ref())?;
|
||||||
let (newpath, newpath_) =
|
|
||||||
deno_fs::resolve_from_cwd(inner.newpath().unwrap())?;
|
|
||||||
|
|
||||||
state.check_read(&oldpath_)?;
|
state.check_read(&oldpath_)?;
|
||||||
state.check_write(&oldpath_)?;
|
state.check_write(&oldpath_)?;
|
||||||
state.check_write(&newpath_)?;
|
state.check_write(&newpath_)?;
|
||||||
|
|
||||||
blocking(base.sync(), move || {
|
let is_sync = args.promise_id.is_none();
|
||||||
|
blocking_json(is_sync, move || {
|
||||||
debug!("op_rename {} {}", oldpath.display(), newpath.display());
|
debug!("op_rename {} {}", oldpath.display(), newpath.display());
|
||||||
fs::rename(&oldpath, &newpath)?;
|
fs::rename(&oldpath, &newpath)?;
|
||||||
Ok(empty_buf())
|
Ok(json!({}))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct LinkArgs {
|
||||||
|
promise_id: Option<u64>,
|
||||||
|
oldname: String,
|
||||||
|
newname: String,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn op_link(
|
pub fn op_link(
|
||||||
state: &ThreadSafeState,
|
state: &ThreadSafeState,
|
||||||
base: &msg::Base<'_>,
|
args: Value,
|
||||||
data: Option<PinnedBuf>,
|
_zero_copy: Option<PinnedBuf>,
|
||||||
) -> CliOpResult {
|
) -> Result<JsonOp, ErrBox> {
|
||||||
assert!(data.is_none());
|
let args: LinkArgs = serde_json::from_value(args)?;
|
||||||
let inner = base.inner_as_link().unwrap();
|
|
||||||
let (oldname, oldpath_) =
|
|
||||||
deno_fs::resolve_from_cwd(inner.oldname().unwrap())?;
|
|
||||||
let (newname, newname_) =
|
|
||||||
deno_fs::resolve_from_cwd(inner.newname().unwrap())?;
|
|
||||||
|
|
||||||
state.check_read(&oldpath_)?;
|
let (oldname, oldname_) = deno_fs::resolve_from_cwd(args.oldname.as_ref())?;
|
||||||
|
let (newname, newname_) = deno_fs::resolve_from_cwd(args.newname.as_ref())?;
|
||||||
|
|
||||||
|
state.check_read(&oldname_)?;
|
||||||
state.check_write(&newname_)?;
|
state.check_write(&newname_)?;
|
||||||
|
|
||||||
blocking(base.sync(), move || {
|
let is_sync = args.promise_id.is_none();
|
||||||
|
blocking_json(is_sync, move || {
|
||||||
debug!("op_link {} {}", oldname.display(), newname.display());
|
debug!("op_link {} {}", oldname.display(), newname.display());
|
||||||
std::fs::hard_link(&oldname, &newname)?;
|
std::fs::hard_link(&oldname, &newname)?;
|
||||||
Ok(empty_buf())
|
Ok(json!({}))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct SymlinkArgs {
|
||||||
|
promise_id: Option<u64>,
|
||||||
|
oldname: String,
|
||||||
|
newname: String,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn op_symlink(
|
pub fn op_symlink(
|
||||||
state: &ThreadSafeState,
|
state: &ThreadSafeState,
|
||||||
base: &msg::Base<'_>,
|
args: Value,
|
||||||
data: Option<PinnedBuf>,
|
_zero_copy: Option<PinnedBuf>,
|
||||||
) -> CliOpResult {
|
) -> Result<JsonOp, ErrBox> {
|
||||||
assert!(data.is_none());
|
let args: SymlinkArgs = serde_json::from_value(args)?;
|
||||||
let inner = base.inner_as_symlink().unwrap();
|
|
||||||
let (oldname, _) = deno_fs::resolve_from_cwd(inner.oldname().unwrap())?;
|
let (oldname, _oldname_) = deno_fs::resolve_from_cwd(args.oldname.as_ref())?;
|
||||||
let (newname, newname_) =
|
let (newname, newname_) = deno_fs::resolve_from_cwd(args.newname.as_ref())?;
|
||||||
deno_fs::resolve_from_cwd(inner.newname().unwrap())?;
|
|
||||||
|
|
||||||
state.check_write(&newname_)?;
|
state.check_write(&newname_)?;
|
||||||
// TODO Use type for Windows.
|
// TODO Use type for Windows.
|
||||||
|
@ -345,88 +384,97 @@ pub fn op_symlink(
|
||||||
DenoError::new(ErrorKind::Other, "Not implemented".to_string()).into(),
|
DenoError::new(ErrorKind::Other, "Not implemented".to_string()).into(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
blocking(base.sync(), move || {
|
let is_sync = args.promise_id.is_none();
|
||||||
|
blocking_json(is_sync, move || {
|
||||||
debug!("op_symlink {} {}", oldname.display(), newname.display());
|
debug!("op_symlink {} {}", oldname.display(), newname.display());
|
||||||
#[cfg(any(unix))]
|
#[cfg(any(unix))]
|
||||||
std::os::unix::fs::symlink(&oldname, &newname)?;
|
std::os::unix::fs::symlink(&oldname, &newname)?;
|
||||||
Ok(empty_buf())
|
Ok(json!({}))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct ReadLinkArgs {
|
||||||
|
promise_id: Option<u64>,
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn op_read_link(
|
pub fn op_read_link(
|
||||||
state: &ThreadSafeState,
|
state: &ThreadSafeState,
|
||||||
base: &msg::Base<'_>,
|
args: Value,
|
||||||
data: Option<PinnedBuf>,
|
_zero_copy: Option<PinnedBuf>,
|
||||||
) -> CliOpResult {
|
) -> Result<JsonOp, ErrBox> {
|
||||||
assert!(data.is_none());
|
let args: ReadLinkArgs = serde_json::from_value(args)?;
|
||||||
let inner = base.inner_as_readlink().unwrap();
|
|
||||||
let cmd_id = base.cmd_id();
|
let (name, name_) = deno_fs::resolve_from_cwd(args.name.as_ref())?;
|
||||||
let (name, name_) = deno_fs::resolve_from_cwd(inner.name().unwrap())?;
|
|
||||||
|
|
||||||
state.check_read(&name_)?;
|
state.check_read(&name_)?;
|
||||||
|
|
||||||
blocking(base.sync(), move || {
|
let is_sync = args.promise_id.is_none();
|
||||||
|
blocking_json(is_sync, move || {
|
||||||
debug!("op_read_link {}", name.display());
|
debug!("op_read_link {}", name.display());
|
||||||
let path = fs::read_link(&name)?;
|
let path = fs::read_link(&name)?;
|
||||||
let builder = &mut FlatBufferBuilder::new();
|
let path_str = path.to_str().unwrap();
|
||||||
let path_off = builder.create_string(path.to_str().unwrap());
|
|
||||||
let inner = msg::ReadlinkRes::create(
|
Ok(json!(path_str))
|
||||||
builder,
|
|
||||||
&msg::ReadlinkResArgs {
|
|
||||||
path: Some(path_off),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
Ok(serialize_response(
|
|
||||||
cmd_id,
|
|
||||||
builder,
|
|
||||||
msg::BaseArgs {
|
|
||||||
inner: Some(inner.as_union_value()),
|
|
||||||
inner_type: msg::Any::ReadlinkRes,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct TruncateArgs {
|
||||||
|
promise_id: Option<u64>,
|
||||||
|
name: String,
|
||||||
|
len: u64,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn op_truncate(
|
pub fn op_truncate(
|
||||||
state: &ThreadSafeState,
|
state: &ThreadSafeState,
|
||||||
base: &msg::Base<'_>,
|
args: Value,
|
||||||
data: Option<PinnedBuf>,
|
_zero_copy: Option<PinnedBuf>,
|
||||||
) -> CliOpResult {
|
) -> Result<JsonOp, ErrBox> {
|
||||||
assert!(data.is_none());
|
let args: TruncateArgs = serde_json::from_value(args)?;
|
||||||
|
|
||||||
let inner = base.inner_as_truncate().unwrap();
|
let (filename, filename_) = deno_fs::resolve_from_cwd(args.name.as_ref())?;
|
||||||
let (filename, filename_) = deno_fs::resolve_from_cwd(inner.name().unwrap())?;
|
let len = args.len;
|
||||||
let len = inner.len();
|
|
||||||
|
|
||||||
state.check_write(&filename_)?;
|
state.check_write(&filename_)?;
|
||||||
|
|
||||||
blocking(base.sync(), move || {
|
let is_sync = args.promise_id.is_none();
|
||||||
|
blocking_json(is_sync, move || {
|
||||||
debug!("op_truncate {} {}", filename_, len);
|
debug!("op_truncate {} {}", filename_, len);
|
||||||
let f = fs::OpenOptions::new().write(true).open(&filename)?;
|
let f = fs::OpenOptions::new().write(true).open(&filename)?;
|
||||||
f.set_len(u64::from(len))?;
|
f.set_len(len)?;
|
||||||
Ok(empty_buf())
|
Ok(json!({}))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct MakeTempDirArgs {
|
||||||
|
promise_id: Option<u64>,
|
||||||
|
dir: Option<String>,
|
||||||
|
prefix: Option<String>,
|
||||||
|
suffix: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn op_make_temp_dir(
|
pub fn op_make_temp_dir(
|
||||||
state: &ThreadSafeState,
|
state: &ThreadSafeState,
|
||||||
base: &msg::Base<'_>,
|
args: Value,
|
||||||
data: Option<PinnedBuf>,
|
_zero_copy: Option<PinnedBuf>,
|
||||||
) -> CliOpResult {
|
) -> Result<JsonOp, ErrBox> {
|
||||||
assert!(data.is_none());
|
let args: MakeTempDirArgs = serde_json::from_value(args)?;
|
||||||
let base = Box::new(*base);
|
|
||||||
let inner = base.inner_as_make_temp_dir().unwrap();
|
|
||||||
let cmd_id = base.cmd_id();
|
|
||||||
|
|
||||||
// FIXME
|
// FIXME
|
||||||
state.check_write("make_temp")?;
|
state.check_write("make_temp")?;
|
||||||
|
|
||||||
let dir = inner.dir().map(PathBuf::from);
|
let dir = args.dir.map(PathBuf::from);
|
||||||
let prefix = inner.prefix().map(String::from);
|
let prefix = args.prefix.map(String::from);
|
||||||
let suffix = inner.suffix().map(String::from);
|
let suffix = args.suffix.map(String::from);
|
||||||
|
|
||||||
blocking(base.sync(), move || {
|
let is_sync = args.promise_id.is_none();
|
||||||
|
blocking_json(is_sync, move || {
|
||||||
// TODO(piscisaureus): use byte vector for paths, not a string.
|
// TODO(piscisaureus): use byte vector for paths, not a string.
|
||||||
// See https://github.com/denoland/deno/issues/627.
|
// See https://github.com/denoland/deno/issues/627.
|
||||||
// We can't assume that paths are always valid utf8 strings.
|
// We can't assume that paths are always valid utf8 strings.
|
||||||
|
@ -436,23 +484,9 @@ pub fn op_make_temp_dir(
|
||||||
prefix.as_ref().map(|x| &**x),
|
prefix.as_ref().map(|x| &**x),
|
||||||
suffix.as_ref().map(|x| &**x),
|
suffix.as_ref().map(|x| &**x),
|
||||||
)?;
|
)?;
|
||||||
let builder = &mut FlatBufferBuilder::new();
|
let path_str = path.to_str().unwrap();
|
||||||
let path_off = builder.create_string(path.to_str().unwrap());
|
|
||||||
let inner = msg::MakeTempDirRes::create(
|
Ok(json!(path_str))
|
||||||
builder,
|
|
||||||
&msg::MakeTempDirResArgs {
|
|
||||||
path: Some(path_off),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
Ok(serialize_response(
|
|
||||||
cmd_id,
|
|
||||||
builder,
|
|
||||||
msg::BaseArgs {
|
|
||||||
inner: Some(inner.as_union_value()),
|
|
||||||
inner_type: msg::Any::MakeTempDirRes,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,24 +516,10 @@ pub fn op_utime(
|
||||||
|
|
||||||
pub fn op_cwd(
|
pub fn op_cwd(
|
||||||
_state: &ThreadSafeState,
|
_state: &ThreadSafeState,
|
||||||
base: &msg::Base<'_>,
|
_args: Value,
|
||||||
data: Option<PinnedBuf>,
|
_zero_copy: Option<PinnedBuf>,
|
||||||
) -> CliOpResult {
|
) -> Result<JsonOp, ErrBox> {
|
||||||
assert!(data.is_none());
|
|
||||||
let cmd_id = base.cmd_id();
|
|
||||||
let path = std::env::current_dir()?;
|
let path = std::env::current_dir()?;
|
||||||
let builder = &mut FlatBufferBuilder::new();
|
let path_str = path.into_os_string().into_string().unwrap();
|
||||||
let cwd =
|
Ok(JsonOp::Sync(json!(path_str)))
|
||||||
builder.create_string(&path.into_os_string().into_string().unwrap());
|
|
||||||
let inner = msg::CwdRes::create(builder, &msg::CwdResArgs { cwd: Some(cwd) });
|
|
||||||
let response_buf = serialize_response(
|
|
||||||
cmd_id,
|
|
||||||
builder,
|
|
||||||
msg::BaseArgs {
|
|
||||||
inner: Some(inner.as_union_value()),
|
|
||||||
inner_type: msg::Any::CwdRes,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
);
|
|
||||||
ok_buf(response_buf)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ mod workers;
|
||||||
|
|
||||||
// Warning! These values are duplicated in the TypeScript code (js/dispatch.ts),
|
// Warning! These values are duplicated in the TypeScript code (js/dispatch.ts),
|
||||||
// update with care.
|
// update with care.
|
||||||
pub const OP_FLATBUFFER: OpId = 44;
|
pub const OP_FLATBUFFER: OpId = 100;
|
||||||
pub const OP_READ: OpId = 1;
|
pub const OP_READ: OpId = 1;
|
||||||
pub const OP_WRITE: OpId = 2;
|
pub const OP_WRITE: OpId = 2;
|
||||||
pub const OP_EXIT: OpId = 3;
|
pub const OP_EXIT: OpId = 3;
|
||||||
|
@ -68,6 +68,21 @@ pub const OP_WORKER_GET_MESSAGE: OpId = 38;
|
||||||
pub const OP_RUN: OpId = 39;
|
pub const OP_RUN: OpId = 39;
|
||||||
pub const OP_RUN_STATUS: OpId = 40;
|
pub const OP_RUN_STATUS: OpId = 40;
|
||||||
pub const OP_KILL: OpId = 41;
|
pub const OP_KILL: OpId = 41;
|
||||||
|
pub const OP_CHDIR: OpId = 42;
|
||||||
|
pub const OP_MKDIR: OpId = 43;
|
||||||
|
pub const OP_CHMOD: OpId = 44;
|
||||||
|
pub const OP_CHOWN: OpId = 45;
|
||||||
|
pub const OP_REMOVE: OpId = 46;
|
||||||
|
pub const OP_COPY_FILE: OpId = 47;
|
||||||
|
pub const OP_STAT: OpId = 48;
|
||||||
|
pub const OP_READ_DIR: OpId = 49;
|
||||||
|
pub const OP_RENAME: OpId = 50;
|
||||||
|
pub const OP_LINK: OpId = 51;
|
||||||
|
pub const OP_SYMLINK: OpId = 52;
|
||||||
|
pub const OP_READ_LINK: OpId = 53;
|
||||||
|
pub const OP_TRUNCATE: OpId = 54;
|
||||||
|
pub const OP_MAKE_TEMP_DIR: OpId = 55;
|
||||||
|
pub const OP_CWD: OpId = 56;
|
||||||
|
|
||||||
pub fn dispatch(
|
pub fn dispatch(
|
||||||
state: &ThreadSafeState,
|
state: &ThreadSafeState,
|
||||||
|
@ -242,6 +257,45 @@ pub fn dispatch(
|
||||||
OP_KILL => {
|
OP_KILL => {
|
||||||
dispatch_json::dispatch(process::op_kill, state, control, zero_copy)
|
dispatch_json::dispatch(process::op_kill, state, control, zero_copy)
|
||||||
}
|
}
|
||||||
|
OP_CHDIR => {
|
||||||
|
dispatch_json::dispatch(fs::op_chdir, state, control, zero_copy)
|
||||||
|
}
|
||||||
|
OP_MKDIR => {
|
||||||
|
dispatch_json::dispatch(fs::op_mkdir, state, control, zero_copy)
|
||||||
|
}
|
||||||
|
OP_CHMOD => {
|
||||||
|
dispatch_json::dispatch(fs::op_chmod, state, control, zero_copy)
|
||||||
|
}
|
||||||
|
OP_CHOWN => {
|
||||||
|
dispatch_json::dispatch(fs::op_chown, state, control, zero_copy)
|
||||||
|
}
|
||||||
|
OP_REMOVE => {
|
||||||
|
dispatch_json::dispatch(fs::op_remove, state, control, zero_copy)
|
||||||
|
}
|
||||||
|
OP_COPY_FILE => {
|
||||||
|
dispatch_json::dispatch(fs::op_copy_file, state, control, zero_copy)
|
||||||
|
}
|
||||||
|
OP_STAT => dispatch_json::dispatch(fs::op_stat, state, control, zero_copy),
|
||||||
|
OP_READ_DIR => {
|
||||||
|
dispatch_json::dispatch(fs::op_read_dir, state, control, zero_copy)
|
||||||
|
}
|
||||||
|
OP_RENAME => {
|
||||||
|
dispatch_json::dispatch(fs::op_rename, state, control, zero_copy)
|
||||||
|
}
|
||||||
|
OP_LINK => dispatch_json::dispatch(fs::op_link, state, control, zero_copy),
|
||||||
|
OP_SYMLINK => {
|
||||||
|
dispatch_json::dispatch(fs::op_symlink, state, control, zero_copy)
|
||||||
|
}
|
||||||
|
OP_READ_LINK => {
|
||||||
|
dispatch_json::dispatch(fs::op_read_link, state, control, zero_copy)
|
||||||
|
}
|
||||||
|
OP_TRUNCATE => {
|
||||||
|
dispatch_json::dispatch(fs::op_truncate, state, control, zero_copy)
|
||||||
|
}
|
||||||
|
OP_MAKE_TEMP_DIR => {
|
||||||
|
dispatch_json::dispatch(fs::op_make_temp_dir, state, control, zero_copy)
|
||||||
|
}
|
||||||
|
OP_CWD => dispatch_json::dispatch(fs::op_cwd, state, control, zero_copy),
|
||||||
OP_FLATBUFFER => dispatch_flatbuffers::dispatch(state, control, zero_copy),
|
OP_FLATBUFFER => dispatch_flatbuffers::dispatch(state, control, zero_copy),
|
||||||
_ => panic!("bad op_id"),
|
_ => panic!("bad op_id"),
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#![allow(dead_code)]
|
||||||
use crate::tokio_util;
|
use crate::tokio_util;
|
||||||
use deno::Buf;
|
use deno::Buf;
|
||||||
use deno::ErrBox;
|
use deno::ErrBox;
|
||||||
|
|
17
js/chmod.ts
17
js/chmod.ts
|
@ -1,15 +1,6 @@
|
||||||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||||
import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers";
|
import { sendSync, sendAsync } from "./dispatch_json";
|
||||||
|
import * as dispatch from "./dispatch";
|
||||||
function req(
|
|
||||||
path: string,
|
|
||||||
mode: number
|
|
||||||
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
|
|
||||||
const builder = flatbuffers.createBuilder();
|
|
||||||
const path_ = builder.createString(path);
|
|
||||||
const inner = msg.Chmod.createChmod(builder, path_, mode);
|
|
||||||
return [builder, msg.Any.Chmod, inner];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Changes the permission of a specific file/directory of specified path
|
/** Changes the permission of a specific file/directory of specified path
|
||||||
* synchronously.
|
* synchronously.
|
||||||
|
@ -17,7 +8,7 @@ function req(
|
||||||
* Deno.chmodSync("/path/to/file", 0o666);
|
* Deno.chmodSync("/path/to/file", 0o666);
|
||||||
*/
|
*/
|
||||||
export function chmodSync(path: string, mode: number): void {
|
export function chmodSync(path: string, mode: number): void {
|
||||||
sendSync(...req(path, mode));
|
sendSync(dispatch.OP_CHMOD, { path, mode });
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Changes the permission of a specific file/directory of specified path.
|
/** Changes the permission of a specific file/directory of specified path.
|
||||||
|
@ -25,5 +16,5 @@ export function chmodSync(path: string, mode: number): void {
|
||||||
* await Deno.chmod("/path/to/file", 0o666);
|
* await Deno.chmod("/path/to/file", 0o666);
|
||||||
*/
|
*/
|
||||||
export async function chmod(path: string, mode: number): Promise<void> {
|
export async function chmod(path: string, mode: number): Promise<void> {
|
||||||
await sendAsync(...req(path, mode));
|
await sendAsync(dispatch.OP_CHMOD, { path, mode });
|
||||||
}
|
}
|
||||||
|
|
18
js/chown.ts
18
js/chown.ts
|
@ -1,16 +1,6 @@
|
||||||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||||
import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers";
|
import { sendSync, sendAsync } from "./dispatch_json";
|
||||||
|
import * as dispatch from "./dispatch";
|
||||||
function req(
|
|
||||||
path: string,
|
|
||||||
uid: number,
|
|
||||||
gid: number
|
|
||||||
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
|
|
||||||
const builder = flatbuffers.createBuilder();
|
|
||||||
const path_ = builder.createString(path);
|
|
||||||
const inner = msg.Chown.createChown(builder, path_, uid, gid);
|
|
||||||
return [builder, msg.Any.Chown, inner];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change owner of a regular file or directory synchronously. Unix only at the moment.
|
* Change owner of a regular file or directory synchronously. Unix only at the moment.
|
||||||
|
@ -19,7 +9,7 @@ function req(
|
||||||
* @param gid group id of the new owner
|
* @param gid group id of the new owner
|
||||||
*/
|
*/
|
||||||
export function chownSync(path: string, uid: number, gid: number): void {
|
export function chownSync(path: string, uid: number, gid: number): void {
|
||||||
sendSync(...req(path, uid, gid));
|
sendSync(dispatch.OP_CHOWN, { path, uid, gid });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,5 +23,5 @@ export async function chown(
|
||||||
uid: number,
|
uid: number,
|
||||||
gid: number
|
gid: number
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
await sendAsync(...req(path, uid, gid));
|
await sendAsync(dispatch.OP_CHOWN, { path, uid, gid });
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,6 @@
|
||||||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||||
import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers";
|
import { sendSync, sendAsync } from "./dispatch_json";
|
||||||
|
import * as dispatch from "./dispatch";
|
||||||
function req(
|
|
||||||
from: string,
|
|
||||||
to: string
|
|
||||||
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
|
|
||||||
const builder = flatbuffers.createBuilder();
|
|
||||||
const from_ = builder.createString(from);
|
|
||||||
const to_ = builder.createString(to);
|
|
||||||
const inner = msg.CopyFile.createCopyFile(builder, from_, to_);
|
|
||||||
return [builder, msg.Any.CopyFile, inner];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Copies the contents of a file to another by name synchronously.
|
/** Copies the contents of a file to another by name synchronously.
|
||||||
* Creates a new file if target does not exists, and if target exists,
|
* Creates a new file if target does not exists, and if target exists,
|
||||||
|
@ -22,7 +12,7 @@ function req(
|
||||||
* Deno.copyFileSync("from.txt", "to.txt");
|
* Deno.copyFileSync("from.txt", "to.txt");
|
||||||
*/
|
*/
|
||||||
export function copyFileSync(from: string, to: string): void {
|
export function copyFileSync(from: string, to: string): void {
|
||||||
sendSync(...req(from, to));
|
sendSync(dispatch.OP_COPY_FILE, { from, to });
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Copies the contents of a file to another by name.
|
/** Copies the contents of a file to another by name.
|
||||||
|
@ -36,5 +26,5 @@ export function copyFileSync(from: string, to: string): void {
|
||||||
* await Deno.copyFile("from.txt", "to.txt");
|
* await Deno.copyFile("from.txt", "to.txt");
|
||||||
*/
|
*/
|
||||||
export async function copyFile(from: string, to: string): Promise<void> {
|
export async function copyFile(from: string, to: string): Promise<void> {
|
||||||
await sendAsync(...req(from, to));
|
await sendAsync(dispatch.OP_COPY_FILE, { from, to });
|
||||||
}
|
}
|
||||||
|
|
19
js/dir.ts
19
js/dir.ts
|
@ -1,6 +1,6 @@
|
||||||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||||
import { assert } from "./util";
|
import { sendSync } from "./dispatch_json";
|
||||||
import { sendSync, flatbuffers, msg } from "./dispatch_flatbuffers";
|
import * as dispatch from "./dispatch";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `cwd()` Return a string representing the current working directory.
|
* `cwd()` Return a string representing the current working directory.
|
||||||
|
@ -10,15 +10,7 @@ import { sendSync, flatbuffers, msg } from "./dispatch_flatbuffers";
|
||||||
* throws `NotFound` exception if directory not available
|
* throws `NotFound` exception if directory not available
|
||||||
*/
|
*/
|
||||||
export function cwd(): string {
|
export function cwd(): string {
|
||||||
const builder = flatbuffers.createBuilder();
|
return sendSync(dispatch.OP_CWD);
|
||||||
msg.Cwd.startCwd(builder);
|
|
||||||
const inner = msg.Cwd.endCwd(builder);
|
|
||||||
const baseRes = sendSync(builder, msg.Any.Cwd, inner);
|
|
||||||
assert(baseRes != null);
|
|
||||||
assert(msg.Any.CwdRes === baseRes!.innerType());
|
|
||||||
const res = new msg.CwdRes();
|
|
||||||
assert(baseRes!.inner(res) != null);
|
|
||||||
return res.cwd()!;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,8 +18,5 @@ export function cwd(): string {
|
||||||
* throws `NotFound` exception if directory not available
|
* throws `NotFound` exception if directory not available
|
||||||
*/
|
*/
|
||||||
export function chdir(directory: string): void {
|
export function chdir(directory: string): void {
|
||||||
const builder = flatbuffers.createBuilder();
|
sendSync(dispatch.OP_CHDIR, { directory });
|
||||||
const directory_ = builder.createString(directory);
|
|
||||||
const inner = msg.Chdir.createChdir(builder, directory_);
|
|
||||||
sendSync(builder, msg.Any.Chdir, inner);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import * as flatbuffers from "./dispatch_flatbuffers";
|
||||||
import * as json from "./dispatch_json";
|
import * as json from "./dispatch_json";
|
||||||
|
|
||||||
// These consts are shared with Rust. Update with care.
|
// These consts are shared with Rust. Update with care.
|
||||||
export const OP_FLATBUFFER = 44;
|
export const OP_FLATBUFFER = 100;
|
||||||
export const OP_READ = 1;
|
export const OP_READ = 1;
|
||||||
export const OP_WRITE = 2;
|
export const OP_WRITE = 2;
|
||||||
export const OP_EXIT = 3;
|
export const OP_EXIT = 3;
|
||||||
|
@ -46,6 +46,21 @@ export const OP_WORKER_GET_MESSAGE = 38;
|
||||||
export const OP_RUN = 39;
|
export const OP_RUN = 39;
|
||||||
export const OP_RUN_STATUS = 40;
|
export const OP_RUN_STATUS = 40;
|
||||||
export const OP_KILL = 41;
|
export const OP_KILL = 41;
|
||||||
|
export const OP_CHDIR = 42;
|
||||||
|
export const OP_MKDIR = 43;
|
||||||
|
export const OP_CHMOD = 44;
|
||||||
|
export const OP_CHOWN = 45;
|
||||||
|
export const OP_REMOVE = 46;
|
||||||
|
export const OP_COPY_FILE = 47;
|
||||||
|
export const OP_STAT = 48;
|
||||||
|
export const OP_READ_DIR = 49;
|
||||||
|
export const OP_RENAME = 50;
|
||||||
|
export const OP_LINK = 51;
|
||||||
|
export const OP_SYMLINK = 52;
|
||||||
|
export const OP_READ_LINK = 53;
|
||||||
|
export const OP_TRUNCATE = 54;
|
||||||
|
export const OP_MAKE_TEMP_DIR = 55;
|
||||||
|
export const OP_CWD = 56;
|
||||||
|
|
||||||
export function asyncMsgFromRust(opId: number, ui8: Uint8Array): void {
|
export function asyncMsgFromRust(opId: number, ui8: Uint8Array): void {
|
||||||
switch (opId) {
|
switch (opId) {
|
||||||
|
@ -73,6 +88,19 @@ export function asyncMsgFromRust(opId: number, ui8: Uint8Array): void {
|
||||||
case OP_HOST_GET_MESSAGE:
|
case OP_HOST_GET_MESSAGE:
|
||||||
case OP_WORKER_GET_MESSAGE:
|
case OP_WORKER_GET_MESSAGE:
|
||||||
case OP_RUN_STATUS:
|
case OP_RUN_STATUS:
|
||||||
|
case OP_MKDIR:
|
||||||
|
case OP_CHMOD:
|
||||||
|
case OP_CHOWN:
|
||||||
|
case OP_REMOVE:
|
||||||
|
case OP_COPY_FILE:
|
||||||
|
case OP_STAT:
|
||||||
|
case OP_READ_DIR:
|
||||||
|
case OP_RENAME:
|
||||||
|
case OP_LINK:
|
||||||
|
case OP_SYMLINK:
|
||||||
|
case OP_READ_LINK:
|
||||||
|
case OP_TRUNCATE:
|
||||||
|
case OP_MAKE_TEMP_DIR:
|
||||||
json.asyncMsgFromRust(opId, ui8);
|
json.asyncMsgFromRust(opId, ui8);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||||
import * as msg from "gen/cli/msg_generated";
|
import { StatResponse } from "./stat";
|
||||||
|
|
||||||
/** A FileInfo describes a file and is returned by `stat`, `lstat`,
|
/** A FileInfo describes a file and is returned by `stat`, `lstat`,
|
||||||
* `statSync`, `lstatSync`.
|
* `statSync`, `lstatSync`.
|
||||||
|
@ -58,17 +58,17 @@ export class FileInfoImpl implements FileInfo {
|
||||||
name: string | null;
|
name: string | null;
|
||||||
|
|
||||||
/* @internal */
|
/* @internal */
|
||||||
constructor(private _inner: msg.StatRes) {
|
constructor(private _res: StatResponse) {
|
||||||
const modified = this._inner.modified().toFloat64();
|
const modified = this._res.modified;
|
||||||
const accessed = this._inner.accessed().toFloat64();
|
const accessed = this._res.accessed;
|
||||||
const created = this._inner.created().toFloat64();
|
const created = this._res.created;
|
||||||
const hasMode = this._inner.hasMode();
|
const hasMode = this._res.hasMode;
|
||||||
const mode = this._inner.mode(); // negative for invalid mode (Windows)
|
const mode = this._res.mode; // negative for invalid mode (Windows)
|
||||||
const name = this._inner.name();
|
const name = this._res.name;
|
||||||
|
|
||||||
this._isFile = this._inner.isFile();
|
this._isFile = this._res.isFile;
|
||||||
this._isSymlink = this._inner.isSymlink();
|
this._isSymlink = this._res.isSymlink;
|
||||||
this.len = this._inner.len().toFloat64();
|
this.len = this._res.len;
|
||||||
this.modified = modified ? modified : null;
|
this.modified = modified ? modified : null;
|
||||||
this.accessed = accessed ? accessed : null;
|
this.accessed = accessed ? accessed : null;
|
||||||
this.created = created ? created : null;
|
this.created = created ? created : null;
|
||||||
|
|
18
js/link.ts
18
js/link.ts
|
@ -1,23 +1,13 @@
|
||||||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||||
import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers";
|
import { sendSync, sendAsync } from "./dispatch_json";
|
||||||
|
import * as dispatch from "./dispatch";
|
||||||
function req(
|
|
||||||
oldname: string,
|
|
||||||
newname: string
|
|
||||||
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
|
|
||||||
const builder = flatbuffers.createBuilder();
|
|
||||||
const oldname_ = builder.createString(oldname);
|
|
||||||
const newname_ = builder.createString(newname);
|
|
||||||
const inner = msg.Link.createLink(builder, oldname_, newname_);
|
|
||||||
return [builder, msg.Any.Link, inner];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Synchronously creates `newname` as a hard link to `oldname`.
|
/** Synchronously creates `newname` as a hard link to `oldname`.
|
||||||
*
|
*
|
||||||
* Deno.linkSync("old/name", "new/name");
|
* Deno.linkSync("old/name", "new/name");
|
||||||
*/
|
*/
|
||||||
export function linkSync(oldname: string, newname: string): void {
|
export function linkSync(oldname: string, newname: string): void {
|
||||||
sendSync(...req(oldname, newname));
|
sendSync(dispatch.OP_LINK, { oldname, newname });
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Creates `newname` as a hard link to `oldname`.
|
/** Creates `newname` as a hard link to `oldname`.
|
||||||
|
@ -25,5 +15,5 @@ export function linkSync(oldname: string, newname: string): void {
|
||||||
* await Deno.link("old/name", "new/name");
|
* await Deno.link("old/name", "new/name");
|
||||||
*/
|
*/
|
||||||
export async function link(oldname: string, newname: string): Promise<void> {
|
export async function link(oldname: string, newname: string): Promise<void> {
|
||||||
await sendAsync(...req(oldname, newname));
|
await sendAsync(dispatch.OP_LINK, { oldname, newname });
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||||
import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers";
|
import { sendSync, sendAsync } from "./dispatch_json";
|
||||||
import { assert } from "./util";
|
import * as dispatch from "./dispatch";
|
||||||
|
|
||||||
export interface MakeTempDirOptions {
|
export interface MakeTempDirOptions {
|
||||||
dir?: string;
|
dir?: string;
|
||||||
|
@ -8,41 +8,13 @@ export interface MakeTempDirOptions {
|
||||||
suffix?: string;
|
suffix?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function req({
|
|
||||||
dir,
|
|
||||||
prefix,
|
|
||||||
suffix
|
|
||||||
}: MakeTempDirOptions): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
|
|
||||||
const builder = flatbuffers.createBuilder();
|
|
||||||
const fbDir = dir == null ? 0 : builder.createString(dir);
|
|
||||||
const fbPrefix = prefix == null ? 0 : builder.createString(prefix);
|
|
||||||
const fbSuffix = suffix == null ? 0 : builder.createString(suffix);
|
|
||||||
const inner = msg.MakeTempDir.createMakeTempDir(
|
|
||||||
builder,
|
|
||||||
fbDir,
|
|
||||||
fbPrefix,
|
|
||||||
fbSuffix
|
|
||||||
);
|
|
||||||
return [builder, msg.Any.MakeTempDir, inner];
|
|
||||||
}
|
|
||||||
|
|
||||||
function res(baseRes: null | msg.Base): string {
|
|
||||||
assert(baseRes != null);
|
|
||||||
assert(msg.Any.MakeTempDirRes === baseRes!.innerType());
|
|
||||||
const res = new msg.MakeTempDirRes();
|
|
||||||
assert(baseRes!.inner(res) != null);
|
|
||||||
const path = res.path();
|
|
||||||
assert(path != null);
|
|
||||||
return path!;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** makeTempDirSync is the synchronous version of `makeTempDir`.
|
/** makeTempDirSync is the synchronous version of `makeTempDir`.
|
||||||
*
|
*
|
||||||
* const tempDirName0 = Deno.makeTempDirSync();
|
* const tempDirName0 = Deno.makeTempDirSync();
|
||||||
* const tempDirName1 = Deno.makeTempDirSync({ prefix: 'my_temp' });
|
* const tempDirName1 = Deno.makeTempDirSync({ prefix: 'my_temp' });
|
||||||
*/
|
*/
|
||||||
export function makeTempDirSync(options: MakeTempDirOptions = {}): string {
|
export function makeTempDirSync(options: MakeTempDirOptions = {}): string {
|
||||||
return res(sendSync(...req(options)));
|
return sendSync(dispatch.OP_MAKE_TEMP_DIR, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** makeTempDir creates a new temporary directory in the directory `dir`, its
|
/** makeTempDir creates a new temporary directory in the directory `dir`, its
|
||||||
|
@ -59,5 +31,5 @@ export function makeTempDirSync(options: MakeTempDirOptions = {}): string {
|
||||||
export async function makeTempDir(
|
export async function makeTempDir(
|
||||||
options: MakeTempDirOptions = {}
|
options: MakeTempDirOptions = {}
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
return res(await sendAsync(...req(options)));
|
return await sendAsync(dispatch.OP_MAKE_TEMP_DIR, options);
|
||||||
}
|
}
|
||||||
|
|
18
js/mkdir.ts
18
js/mkdir.ts
|
@ -1,16 +1,6 @@
|
||||||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||||
import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers";
|
import { sendSync, sendAsync } from "./dispatch_json";
|
||||||
|
import * as dispatch from "./dispatch";
|
||||||
function req(
|
|
||||||
path: string,
|
|
||||||
recursive: boolean,
|
|
||||||
mode: number
|
|
||||||
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
|
|
||||||
const builder = flatbuffers.createBuilder();
|
|
||||||
const path_ = builder.createString(path);
|
|
||||||
const inner = msg.Mkdir.createMkdir(builder, path_, recursive, mode);
|
|
||||||
return [builder, msg.Any.Mkdir, inner];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Creates a new directory with the specified path synchronously.
|
/** Creates a new directory with the specified path synchronously.
|
||||||
* If `recursive` is set to true, nested directories will be created (also known
|
* If `recursive` is set to true, nested directories will be created (also known
|
||||||
|
@ -22,7 +12,7 @@ function req(
|
||||||
* Deno.mkdirSync("nested/directories", true);
|
* Deno.mkdirSync("nested/directories", true);
|
||||||
*/
|
*/
|
||||||
export function mkdirSync(path: string, recursive = false, mode = 0o777): void {
|
export function mkdirSync(path: string, recursive = false, mode = 0o777): void {
|
||||||
sendSync(...req(path, recursive, mode));
|
sendSync(dispatch.OP_MKDIR, { path, recursive, mode });
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Creates a new directory with the specified path.
|
/** Creates a new directory with the specified path.
|
||||||
|
@ -39,5 +29,5 @@ export async function mkdir(
|
||||||
recursive = false,
|
recursive = false,
|
||||||
mode = 0o777
|
mode = 0o777
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
await sendAsync(...req(path, recursive, mode));
|
await sendAsync(dispatch.OP_MKDIR, { path, recursive, mode });
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,19 @@
|
||||||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||||
import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers";
|
import { sendSync, sendAsync } from "./dispatch_json";
|
||||||
|
import * as dispatch from "./dispatch";
|
||||||
import { FileInfo, FileInfoImpl } from "./file_info";
|
import { FileInfo, FileInfoImpl } from "./file_info";
|
||||||
import { assert } from "./util";
|
import { StatResponse } from "./stat";
|
||||||
|
|
||||||
function req(path: string): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
|
interface ReadDirResponse {
|
||||||
const builder = flatbuffers.createBuilder();
|
entries: StatResponse[];
|
||||||
const path_ = builder.createString(path);
|
|
||||||
const inner = msg.ReadDir.createReadDir(builder, path_);
|
|
||||||
return [builder, msg.Any.ReadDir, inner];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function res(baseRes: null | msg.Base): FileInfo[] {
|
function res(response: ReadDirResponse): FileInfo[] {
|
||||||
assert(baseRes != null);
|
return response.entries.map(
|
||||||
assert(msg.Any.ReadDirRes === baseRes!.innerType());
|
(statRes: StatResponse): FileInfo => {
|
||||||
const res = new msg.ReadDirRes();
|
return new FileInfoImpl(statRes);
|
||||||
assert(baseRes!.inner(res) != null);
|
}
|
||||||
const fileInfos: FileInfo[] = [];
|
);
|
||||||
for (let i = 0; i < res.entriesLength(); i++) {
|
|
||||||
fileInfos.push(new FileInfoImpl(res.entries(i)!));
|
|
||||||
}
|
|
||||||
return fileInfos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Reads the directory given by path and returns a list of file info
|
/** Reads the directory given by path and returns a list of file info
|
||||||
|
@ -28,7 +22,7 @@ function res(baseRes: null | msg.Base): FileInfo[] {
|
||||||
* const files = Deno.readDirSync("/");
|
* const files = Deno.readDirSync("/");
|
||||||
*/
|
*/
|
||||||
export function readDirSync(path: string): FileInfo[] {
|
export function readDirSync(path: string): FileInfo[] {
|
||||||
return res(sendSync(...req(path)));
|
return res(sendSync(dispatch.OP_READ_DIR, { path }));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Reads the directory given by path and returns a list of file info.
|
/** Reads the directory given by path and returns a list of file info.
|
||||||
|
@ -36,5 +30,5 @@ export function readDirSync(path: string): FileInfo[] {
|
||||||
* const files = await Deno.readDir("/");
|
* const files = await Deno.readDir("/");
|
||||||
*/
|
*/
|
||||||
export async function readDir(path: string): Promise<FileInfo[]> {
|
export async function readDir(path: string): Promise<FileInfo[]> {
|
||||||
return res(await sendAsync(...req(path)));
|
return res(await sendAsync(dispatch.OP_READ_DIR, { path }));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,13 @@
|
||||||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||||
import { assert } from "./util";
|
import { sendSync, sendAsync } from "./dispatch_json";
|
||||||
import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers";
|
import * as dispatch from "./dispatch";
|
||||||
|
|
||||||
function req(name: string): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
|
|
||||||
const builder = flatbuffers.createBuilder();
|
|
||||||
const name_ = builder.createString(name);
|
|
||||||
const inner = msg.Readlink.createReadlink(builder, name_);
|
|
||||||
return [builder, msg.Any.Readlink, inner];
|
|
||||||
}
|
|
||||||
|
|
||||||
function res(baseRes: null | msg.Base): string {
|
|
||||||
assert(baseRes !== null);
|
|
||||||
assert(msg.Any.ReadlinkRes === baseRes!.innerType());
|
|
||||||
const res = new msg.ReadlinkRes();
|
|
||||||
assert(baseRes!.inner(res) !== null);
|
|
||||||
const path = res.path();
|
|
||||||
assert(path !== null);
|
|
||||||
return path!;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the destination of the named symbolic link synchronously.
|
/** Returns the destination of the named symbolic link synchronously.
|
||||||
*
|
*
|
||||||
* const targetPath = Deno.readlinkSync("symlink/path");
|
* const targetPath = Deno.readlinkSync("symlink/path");
|
||||||
*/
|
*/
|
||||||
export function readlinkSync(name: string): string {
|
export function readlinkSync(name: string): string {
|
||||||
return res(sendSync(...req(name)));
|
return sendSync(dispatch.OP_READ_LINK, { name });
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the destination of the named symbolic link.
|
/** Returns the destination of the named symbolic link.
|
||||||
|
@ -32,5 +15,5 @@ export function readlinkSync(name: string): string {
|
||||||
* const targetPath = await Deno.readlink("symlink/path");
|
* const targetPath = await Deno.readlink("symlink/path");
|
||||||
*/
|
*/
|
||||||
export async function readlink(name: string): Promise<string> {
|
export async function readlink(name: string): Promise<string> {
|
||||||
return res(await sendAsync(...req(name)));
|
return await sendAsync(dispatch.OP_READ_LINK, { name });
|
||||||
}
|
}
|
||||||
|
|
17
js/remove.ts
17
js/remove.ts
|
@ -1,20 +1,11 @@
|
||||||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||||
import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers";
|
import { sendSync, sendAsync } from "./dispatch_json";
|
||||||
|
import * as dispatch from "./dispatch";
|
||||||
|
|
||||||
export interface RemoveOption {
|
export interface RemoveOption {
|
||||||
recursive?: boolean;
|
recursive?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function req(
|
|
||||||
path: string,
|
|
||||||
options: RemoveOption
|
|
||||||
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
|
|
||||||
const builder = flatbuffers.createBuilder();
|
|
||||||
const path_ = builder.createString(path);
|
|
||||||
const inner = msg.Remove.createRemove(builder, path_, !!options.recursive);
|
|
||||||
return [builder, msg.Any.Remove, inner];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Removes the named file or directory synchronously. Would throw
|
/** Removes the named file or directory synchronously. Would throw
|
||||||
* error if permission denied, not found, or directory not empty if `recursive`
|
* error if permission denied, not found, or directory not empty if `recursive`
|
||||||
* set to false.
|
* set to false.
|
||||||
|
@ -23,7 +14,7 @@ function req(
|
||||||
* Deno.removeSync("/path/to/dir/or/file", {recursive: false});
|
* Deno.removeSync("/path/to/dir/or/file", {recursive: false});
|
||||||
*/
|
*/
|
||||||
export function removeSync(path: string, options: RemoveOption = {}): void {
|
export function removeSync(path: string, options: RemoveOption = {}): void {
|
||||||
sendSync(...req(path, options));
|
sendSync(dispatch.OP_REMOVE, { path, recursive: !!options.recursive });
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Removes the named file or directory. Would throw error if
|
/** Removes the named file or directory. Would throw error if
|
||||||
|
@ -37,5 +28,5 @@ export async function remove(
|
||||||
path: string,
|
path: string,
|
||||||
options: RemoveOption = {}
|
options: RemoveOption = {}
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
await sendAsync(...req(path, options));
|
await sendAsync(dispatch.OP_REMOVE, { path, recursive: !!options.recursive });
|
||||||
}
|
}
|
||||||
|
|
18
js/rename.ts
18
js/rename.ts
|
@ -1,16 +1,6 @@
|
||||||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||||
import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers";
|
import { sendSync, sendAsync } from "./dispatch_json";
|
||||||
|
import * as dispatch from "./dispatch";
|
||||||
function req(
|
|
||||||
oldpath: string,
|
|
||||||
newpath: string
|
|
||||||
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
|
|
||||||
const builder = flatbuffers.createBuilder();
|
|
||||||
const oldpath_ = builder.createString(oldpath);
|
|
||||||
const newpath_ = builder.createString(newpath);
|
|
||||||
const inner = msg.Rename.createRename(builder, oldpath_, newpath_);
|
|
||||||
return [builder, msg.Any.Rename, inner];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Synchronously renames (moves) `oldpath` to `newpath`. If `newpath` already
|
/** Synchronously renames (moves) `oldpath` to `newpath`. If `newpath` already
|
||||||
* exists and is not a directory, `renameSync()` replaces it. OS-specific
|
* exists and is not a directory, `renameSync()` replaces it. OS-specific
|
||||||
|
@ -20,7 +10,7 @@ function req(
|
||||||
* Deno.renameSync("old/path", "new/path");
|
* Deno.renameSync("old/path", "new/path");
|
||||||
*/
|
*/
|
||||||
export function renameSync(oldpath: string, newpath: string): void {
|
export function renameSync(oldpath: string, newpath: string): void {
|
||||||
sendSync(...req(oldpath, newpath));
|
sendSync(dispatch.OP_RENAME, { oldpath, newpath });
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Renames (moves) `oldpath` to `newpath`. If `newpath` already exists and is
|
/** Renames (moves) `oldpath` to `newpath`. If `newpath` already exists and is
|
||||||
|
@ -30,5 +20,5 @@ export function renameSync(oldpath: string, newpath: string): void {
|
||||||
* await Deno.rename("old/path", "new/path");
|
* await Deno.rename("old/path", "new/path");
|
||||||
*/
|
*/
|
||||||
export async function rename(oldpath: string, newpath: string): Promise<void> {
|
export async function rename(oldpath: string, newpath: string): Promise<void> {
|
||||||
await sendAsync(...req(oldpath, newpath));
|
await sendAsync(dispatch.OP_RENAME, { oldpath, newpath });
|
||||||
}
|
}
|
||||||
|
|
54
js/stat.ts
54
js/stat.ts
|
@ -1,24 +1,18 @@
|
||||||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||||
import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers";
|
import { sendSync, sendAsync } from "./dispatch_json";
|
||||||
import { assert } from "./util";
|
import * as dispatch from "./dispatch";
|
||||||
import { FileInfo, FileInfoImpl } from "./file_info";
|
import { FileInfo, FileInfoImpl } from "./file_info";
|
||||||
|
|
||||||
function req(
|
export interface StatResponse {
|
||||||
filename: string,
|
isFile: boolean;
|
||||||
lstat: boolean
|
isSymlink: boolean;
|
||||||
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
|
len: number;
|
||||||
const builder = flatbuffers.createBuilder();
|
modified: number;
|
||||||
const filename_ = builder.createString(filename);
|
accessed: number;
|
||||||
const inner = msg.Stat.createStat(builder, filename_, lstat);
|
created: number;
|
||||||
return [builder, msg.Any.Stat, inner];
|
mode: number;
|
||||||
}
|
hasMode: boolean; // false on windows
|
||||||
|
name: string | null;
|
||||||
function res(baseRes: null | msg.Base): FileInfo {
|
|
||||||
assert(baseRes != null);
|
|
||||||
assert(msg.Any.StatRes === baseRes!.innerType());
|
|
||||||
const res = new msg.StatRes();
|
|
||||||
assert(baseRes!.inner(res) != null);
|
|
||||||
return new FileInfoImpl(res);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Queries the file system for information on the path provided. If the given
|
/** Queries the file system for information on the path provided. If the given
|
||||||
|
@ -28,7 +22,11 @@ function res(baseRes: null | msg.Base): FileInfo {
|
||||||
* assert(fileInfo.isFile());
|
* assert(fileInfo.isFile());
|
||||||
*/
|
*/
|
||||||
export async function lstat(filename: string): Promise<FileInfo> {
|
export async function lstat(filename: string): Promise<FileInfo> {
|
||||||
return res(await sendAsync(...req(filename, true)));
|
const res = (await sendAsync(dispatch.OP_STAT, {
|
||||||
|
filename,
|
||||||
|
lstat: true
|
||||||
|
})) as StatResponse;
|
||||||
|
return new FileInfoImpl(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Queries the file system for information on the path provided synchronously.
|
/** Queries the file system for information on the path provided synchronously.
|
||||||
|
@ -39,7 +37,11 @@ export async function lstat(filename: string): Promise<FileInfo> {
|
||||||
* assert(fileInfo.isFile());
|
* assert(fileInfo.isFile());
|
||||||
*/
|
*/
|
||||||
export function lstatSync(filename: string): FileInfo {
|
export function lstatSync(filename: string): FileInfo {
|
||||||
return res(sendSync(...req(filename, true)));
|
const res = sendSync(dispatch.OP_STAT, {
|
||||||
|
filename,
|
||||||
|
lstat: true
|
||||||
|
}) as StatResponse;
|
||||||
|
return new FileInfoImpl(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Queries the file system for information on the path provided. `stat` Will
|
/** Queries the file system for information on the path provided. `stat` Will
|
||||||
|
@ -49,7 +51,11 @@ export function lstatSync(filename: string): FileInfo {
|
||||||
* assert(fileInfo.isFile());
|
* assert(fileInfo.isFile());
|
||||||
*/
|
*/
|
||||||
export async function stat(filename: string): Promise<FileInfo> {
|
export async function stat(filename: string): Promise<FileInfo> {
|
||||||
return res(await sendAsync(...req(filename, false)));
|
const res = (await sendAsync(dispatch.OP_STAT, {
|
||||||
|
filename,
|
||||||
|
lstat: false
|
||||||
|
})) as StatResponse;
|
||||||
|
return new FileInfoImpl(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Queries the file system for information on the path provided synchronously.
|
/** Queries the file system for information on the path provided synchronously.
|
||||||
|
@ -59,5 +65,9 @@ export async function stat(filename: string): Promise<FileInfo> {
|
||||||
* assert(fileInfo.isFile());
|
* assert(fileInfo.isFile());
|
||||||
*/
|
*/
|
||||||
export function statSync(filename: string): FileInfo {
|
export function statSync(filename: string): FileInfo {
|
||||||
return res(sendSync(...req(filename, false)));
|
const res = sendSync(dispatch.OP_STAT, {
|
||||||
|
filename,
|
||||||
|
lstat: false
|
||||||
|
}) as StatResponse;
|
||||||
|
return new FileInfoImpl(res);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,9 @@
|
||||||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||||
import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers";
|
import { sendSync, sendAsync } from "./dispatch_json";
|
||||||
|
import * as dispatch from "./dispatch";
|
||||||
import * as util from "./util";
|
import * as util from "./util";
|
||||||
import { platform } from "./build";
|
import { platform } from "./build";
|
||||||
|
|
||||||
function req(
|
|
||||||
oldname: string,
|
|
||||||
newname: string,
|
|
||||||
type?: string
|
|
||||||
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
|
|
||||||
if (platform.os === "win" && type) {
|
|
||||||
return util.notImplemented();
|
|
||||||
}
|
|
||||||
const builder = flatbuffers.createBuilder();
|
|
||||||
const oldname_ = builder.createString(oldname);
|
|
||||||
const newname_ = builder.createString(newname);
|
|
||||||
const inner = msg.Symlink.createSymlink(builder, oldname_, newname_);
|
|
||||||
return [builder, msg.Any.Symlink, inner];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Synchronously creates `newname` as a symbolic link to `oldname`. The type
|
/** Synchronously creates `newname` as a symbolic link to `oldname`. The type
|
||||||
* argument can be set to `dir` or `file` and is only available on Windows
|
* argument can be set to `dir` or `file` and is only available on Windows
|
||||||
* (ignored on other platforms).
|
* (ignored on other platforms).
|
||||||
|
@ -29,7 +15,10 @@ export function symlinkSync(
|
||||||
newname: string,
|
newname: string,
|
||||||
type?: string
|
type?: string
|
||||||
): void {
|
): void {
|
||||||
sendSync(...req(oldname, newname, type));
|
if (platform.os === "win" && type) {
|
||||||
|
return util.notImplemented();
|
||||||
|
}
|
||||||
|
sendSync(dispatch.OP_SYMLINK, { oldname, newname });
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Creates `newname` as a symbolic link to `oldname`. The type argument can be
|
/** Creates `newname` as a symbolic link to `oldname`. The type argument can be
|
||||||
|
@ -43,5 +32,8 @@ export async function symlink(
|
||||||
newname: string,
|
newname: string,
|
||||||
type?: string
|
type?: string
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
await sendAsync(...req(oldname, newname, type));
|
if (platform.os === "win" && type) {
|
||||||
|
return util.notImplemented();
|
||||||
|
}
|
||||||
|
await sendAsync(dispatch.OP_SYMLINK, { oldname, newname });
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||||
import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers";
|
import { sendSync, sendAsync } from "./dispatch_json";
|
||||||
|
import * as dispatch from "./dispatch";
|
||||||
|
|
||||||
function req(
|
function coerceLen(len?: number): number {
|
||||||
name: string,
|
if (!len) {
|
||||||
len?: number
|
return 0;
|
||||||
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
|
}
|
||||||
const builder = flatbuffers.createBuilder();
|
|
||||||
const name_ = builder.createString(name);
|
if (len < 0) {
|
||||||
len = len && len > 0 ? Math.floor(len) : 0;
|
return 0;
|
||||||
const inner = msg.Truncate.createTruncate(builder, name_, len);
|
}
|
||||||
return [builder, msg.Any.Truncate, inner];
|
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Truncates or extends the specified file synchronously, updating the size of
|
/** Truncates or extends the specified file synchronously, updating the size of
|
||||||
|
@ -18,7 +20,7 @@ function req(
|
||||||
* Deno.truncateSync("hello.txt", 10);
|
* Deno.truncateSync("hello.txt", 10);
|
||||||
*/
|
*/
|
||||||
export function truncateSync(name: string, len?: number): void {
|
export function truncateSync(name: string, len?: number): void {
|
||||||
sendSync(...req(name, len));
|
sendSync(dispatch.OP_TRUNCATE, { name, len: coerceLen(len) });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,5 +30,5 @@ export function truncateSync(name: string, len?: number): void {
|
||||||
* await Deno.truncate("hello.txt", 10);
|
* await Deno.truncate("hello.txt", 10);
|
||||||
*/
|
*/
|
||||||
export async function truncate(name: string, len?: number): Promise<void> {
|
export async function truncate(name: string, len?: number): Promise<void> {
|
||||||
await sendAsync(...req(name, len));
|
await sendAsync(dispatch.OP_TRUNCATE, { name, len: coerceLen(len) });
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue