1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-24 16:19:12 -05:00

port fs ops to JSON (#2812)

This commit is contained in:
Bartek Iwańczuk 2019-08-26 16:18:42 +02:00 committed by Ryan Dahl
parent 520f9631e0
commit a6f6209f52
21 changed files with 480 additions and 637 deletions

View file

@ -1,27 +1,7 @@
union Any {
Chdir,
Chmod,
Chown,
CopyFile,
Cwd,
CwdRes,
Link,
MakeTempDir,
MakeTempDirRes,
Mkdir,
Read,
ReadDir,
ReadDirRes,
ReadRes,
Readlink,
ReadlinkRes,
Remove,
Rename,
Seek,
Stat,
StatRes,
Symlink,
Truncate,
Write,
WriteRes,
}
@ -122,105 +102,11 @@ table FormatErrorRes {
error: string;
}
table Chdir {
directory: string;
}
table KeyValue {
key: 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 {
rid: uint32;
// (ptr, len) is passed as second parameter to Deno.core.send().

View file

@ -6,19 +6,14 @@ use deno::*;
use flatbuffers::FlatBufferBuilder;
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(
state: &ThreadSafeState,
base: &msg::Base<'_>,
data: Option<PinnedBuf>,
) -> CliOpResult;
use super::files::{op_read, op_write};
/// Processes raw messages from JavaScript.
/// This functions invoked every time Deno.core.dispatch() is called.
/// control corresponds to the first argument of Deno.core.dispatch().
@ -125,22 +120,7 @@ pub fn serialize_response(
/// Standard ops set for most isolates
pub fn op_selector_std(inner_type: msg::Any) -> Option<CliDispatchFn> {
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::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),
_ => None,

View file

@ -1,14 +1,12 @@
// 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::utils::*;
use crate::deno_error::DenoError;
use crate::deno_error::ErrorKind;
use crate::fs as deno_fs;
use crate::msg;
use crate::state::ThreadSafeState;
use deno::*;
use flatbuffers::FlatBufferBuilder;
use remove_dir_all::remove_dir_all;
use std::convert::From;
use std::fs;
@ -18,99 +16,130 @@ use std::time::UNIX_EPOCH;
#[cfg(unix)]
use std::os::unix::fs::PermissionsExt;
#[derive(Deserialize)]
struct ChdirArgs {
directory: String,
}
pub fn op_chdir(
_state: &ThreadSafeState,
base: &msg::Base<'_>,
data: Option<PinnedBuf>,
) -> CliOpResult {
assert!(data.is_none());
let inner = base.inner_as_chdir().unwrap();
let directory = inner.directory().unwrap();
std::env::set_current_dir(&directory)?;
ok_buf(empty_buf())
args: Value,
_zero_copy: Option<PinnedBuf>,
) -> Result<JsonOp, ErrBox> {
let args: ChdirArgs = serde_json::from_value(args)?;
std::env::set_current_dir(&args.directory)?;
Ok(JsonOp::Sync(json!({})))
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct MkdirArgs {
promise_id: Option<u64>,
path: String,
recursive: bool,
mode: u32,
}
pub fn op_mkdir(
state: &ThreadSafeState,
base: &msg::Base<'_>,
data: Option<PinnedBuf>,
) -> CliOpResult {
assert!(data.is_none());
let inner = base.inner_as_mkdir().unwrap();
let (path, path_) = deno_fs::resolve_from_cwd(inner.path().unwrap())?;
let recursive = inner.recursive();
let mode = inner.mode();
args: Value,
_zero_copy: Option<PinnedBuf>,
) -> Result<JsonOp, ErrBox> {
let args: MkdirArgs = serde_json::from_value(args)?;
let (path, path_) = deno_fs::resolve_from_cwd(args.path.as_ref())?;
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_);
deno_fs::mkdir(&path, mode, recursive)?;
Ok(empty_buf())
deno_fs::mkdir(&path, args.mode, args.recursive)?;
Ok(json!({}))
})
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct ChmodArgs {
promise_id: Option<u64>,
path: String,
mode: u32,
}
pub fn op_chmod(
state: &ThreadSafeState,
base: &msg::Base<'_>,
data: Option<PinnedBuf>,
) -> CliOpResult {
assert!(data.is_none());
let inner = base.inner_as_chmod().unwrap();
let _mode = inner.mode();
let (path, path_) = deno_fs::resolve_from_cwd(inner.path().unwrap())?;
args: Value,
_zero_copy: Option<PinnedBuf>,
) -> Result<JsonOp, ErrBox> {
let args: ChmodArgs = serde_json::from_value(args)?;
let (path, path_) = deno_fs::resolve_from_cwd(args.path.as_ref())?;
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_);
// Still check file/dir exists on windows
let _metadata = fs::metadata(&path)?;
#[cfg(any(unix))]
{
let mut permissions = _metadata.permissions();
permissions.set_mode(_mode);
permissions.set_mode(args.mode);
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(
state: &ThreadSafeState,
base: &msg::Base<'_>,
data: Option<PinnedBuf>,
) -> CliOpResult {
assert!(data.is_none());
let inner = base.inner_as_chown().unwrap();
let path = String::from(inner.path().unwrap());
let uid = inner.uid();
let gid = inner.gid();
args: Value,
_zero_copy: Option<PinnedBuf>,
) -> Result<JsonOp, ErrBox> {
let args: ChownArgs = serde_json::from_value(args)?;
state.check_write(&path)?;
state.check_write(&args.path)?;
blocking(base.sync(), move || {
debug!("op_chown {}", &path);
match deno_fs::chown(&path, uid, gid) {
Ok(_) => Ok(empty_buf()),
let is_sync = args.promise_id.is_none();
blocking_json(is_sync, move || {
debug!("op_chown {}", &args.path);
match deno_fs::chown(args.path.as_ref(), args.uid, args.gid) {
Ok(_) => Ok(json!({})),
Err(e) => Err(e),
}
})
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct RemoveArgs {
promise_id: Option<u64>,
path: String,
recursive: bool,
}
pub fn op_remove(
state: &ThreadSafeState,
base: &msg::Base<'_>,
data: Option<PinnedBuf>,
) -> CliOpResult {
assert!(data.is_none());
let inner = base.inner_as_remove().unwrap();
let (path, path_) = deno_fs::resolve_from_cwd(inner.path().unwrap())?;
let recursive = inner.recursive();
args: Value,
_zero_copy: Option<PinnedBuf>,
) -> Result<JsonOp, ErrBox> {
let args: RemoveArgs = serde_json::from_value(args)?;
let (path, path_) = deno_fs::resolve_from_cwd(args.path.as_ref())?;
let recursive = args.recursive;
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());
let metadata = fs::metadata(&path)?;
if metadata.is_file() {
@ -120,25 +149,34 @@ pub fn op_remove(
} else {
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(
state: &ThreadSafeState,
base: &msg::Base<'_>,
data: Option<PinnedBuf>,
) -> CliOpResult {
assert!(data.is_none());
let inner = base.inner_as_copy_file().unwrap();
let (from, from_) = deno_fs::resolve_from_cwd(inner.from().unwrap())?;
let (to, to_) = deno_fs::resolve_from_cwd(inner.to().unwrap())?;
args: Value,
_zero_copy: Option<PinnedBuf>,
) -> Result<JsonOp, ErrBox> {
let args: CopyFileArgs = serde_json::from_value(args)?;
let (from, from_) = deno_fs::resolve_from_cwd(args.from.as_ref())?;
let (to, to_) = deno_fs::resolve_from_cwd(args.to.as_ref())?;
state.check_read(&from_)?;
state.check_write(&to_)?;
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
// See https://github.com/rust-lang/rust/issues/54800
// Once the issue is reolved, we should remove this workaround.
@ -150,7 +188,7 @@ pub fn op_copy_file(
}
fs::copy(&from, &to)?;
Ok(empty_buf())
Ok(json!({}))
})
}
@ -174,22 +212,29 @@ fn get_mode(_perm: &fs::Permissions) -> u32 {
0
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct StatArgs {
promise_id: Option<u64>,
filename: String,
lstat: bool,
}
pub fn op_stat(
state: &ThreadSafeState,
base: &msg::Base<'_>,
data: Option<PinnedBuf>,
) -> CliOpResult {
assert!(data.is_none());
let inner = base.inner_as_stat().unwrap();
let cmd_id = base.cmd_id();
args: Value,
_zero_copy: Option<PinnedBuf>,
) -> Result<JsonOp, ErrBox> {
let args: StatArgs = serde_json::from_value(args)?;
let (filename, filename_) =
deno_fs::resolve_from_cwd(inner.filename().unwrap())?;
let lstat = inner.lstat();
deno_fs::resolve_from_cwd(args.filename.as_ref())?;
let lstat = args.lstat;
state.check_read(&filename_)?;
blocking(base.sync(), move || {
let builder = &mut FlatBufferBuilder::new();
let is_sync = args.promise_id.is_none();
blocking_json(is_sync, move || {
debug!("op_stat {} {}", filename.display(), lstat);
let metadata = if lstat {
fs::symlink_metadata(&filename)?
@ -197,146 +242,140 @@ pub fn op_stat(
fs::metadata(&filename)?
};
let inner = msg::StatRes::create(
builder,
&msg::StatResArgs {
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()),
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()
},
))
Ok(json!({
"isFile": metadata.is_file(),
"isSymlink": metadata.file_type().is_symlink(),
"len": metadata.len(),
"modified":to_seconds!(metadata.modified()),
"accessed":to_seconds!(metadata.accessed()),
"created":to_seconds!(metadata.created()),
"mode": get_mode(&metadata.permissions()),
"hasMode": cfg!(target_family = "unix"), // false on windows,
}))
})
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct ReadDirArgs {
promise_id: Option<u64>,
path: String,
}
pub fn op_read_dir(
state: &ThreadSafeState,
base: &msg::Base<'_>,
data: Option<PinnedBuf>,
) -> CliOpResult {
assert!(data.is_none());
let inner = base.inner_as_read_dir().unwrap();
let cmd_id = base.cmd_id();
let (path, path_) = deno_fs::resolve_from_cwd(inner.path().unwrap())?;
args: Value,
_zero_copy: Option<PinnedBuf>,
) -> Result<JsonOp, ErrBox> {
let args: ReadDirArgs = serde_json::from_value(args)?;
let (path, path_) = deno_fs::resolve_from_cwd(args.path.as_ref())?;
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());
let builder = &mut FlatBufferBuilder::new();
let entries: Vec<_> = fs::read_dir(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());
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),
mode: get_mode(&metadata.permissions()),
has_mode: cfg!(target_family = "unix"),
},
)
json!({
"isFile": file_type.is_file(),
"isSymlink": file_type.is_symlink(),
"len": metadata.len(),
"modified": to_seconds!(metadata.modified()),
"accessed": to_seconds!(metadata.accessed()),
"created": to_seconds!(metadata.created()),
"mode": get_mode(&metadata.permissions()),
"name": entry.file_name().to_str().unwrap(),
"hasMode": cfg!(target_family = "unix"), // false on windows,
})
})
.collect();
let entries = builder.create_vector(&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()
},
))
Ok(json!({ "entries": entries }))
})
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct RenameArgs {
promise_id: Option<u64>,
oldpath: String,
newpath: String,
}
pub fn op_rename(
state: &ThreadSafeState,
base: &msg::Base<'_>,
data: Option<PinnedBuf>,
) -> CliOpResult {
assert!(data.is_none());
let inner = base.inner_as_rename().unwrap();
let (oldpath, oldpath_) =
deno_fs::resolve_from_cwd(inner.oldpath().unwrap())?;
let (newpath, newpath_) =
deno_fs::resolve_from_cwd(inner.newpath().unwrap())?;
args: Value,
_zero_copy: Option<PinnedBuf>,
) -> Result<JsonOp, ErrBox> {
let args: RenameArgs = serde_json::from_value(args)?;
let (oldpath, oldpath_) = deno_fs::resolve_from_cwd(args.oldpath.as_ref())?;
let (newpath, newpath_) = deno_fs::resolve_from_cwd(args.newpath.as_ref())?;
state.check_read(&oldpath_)?;
state.check_write(&oldpath_)?;
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());
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(
state: &ThreadSafeState,
base: &msg::Base<'_>,
data: Option<PinnedBuf>,
) -> CliOpResult {
assert!(data.is_none());
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())?;
args: Value,
_zero_copy: Option<PinnedBuf>,
) -> Result<JsonOp, ErrBox> {
let args: LinkArgs = serde_json::from_value(args)?;
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_)?;
blocking(base.sync(), move || {
let is_sync = args.promise_id.is_none();
blocking_json(is_sync, move || {
debug!("op_link {} {}", oldname.display(), newname.display());
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(
state: &ThreadSafeState,
base: &msg::Base<'_>,
data: Option<PinnedBuf>,
) -> CliOpResult {
assert!(data.is_none());
let inner = base.inner_as_symlink().unwrap();
let (oldname, _) = deno_fs::resolve_from_cwd(inner.oldname().unwrap())?;
let (newname, newname_) =
deno_fs::resolve_from_cwd(inner.newname().unwrap())?;
args: Value,
_zero_copy: Option<PinnedBuf>,
) -> Result<JsonOp, ErrBox> {
let args: SymlinkArgs = serde_json::from_value(args)?;
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_write(&newname_)?;
// TODO Use type for Windows.
@ -345,88 +384,97 @@ pub fn op_symlink(
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());
#[cfg(any(unix))]
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(
state: &ThreadSafeState,
base: &msg::Base<'_>,
data: Option<PinnedBuf>,
) -> CliOpResult {
assert!(data.is_none());
let inner = base.inner_as_readlink().unwrap();
let cmd_id = base.cmd_id();
let (name, name_) = deno_fs::resolve_from_cwd(inner.name().unwrap())?;
args: Value,
_zero_copy: Option<PinnedBuf>,
) -> Result<JsonOp, ErrBox> {
let args: ReadLinkArgs = serde_json::from_value(args)?;
let (name, name_) = deno_fs::resolve_from_cwd(args.name.as_ref())?;
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());
let path = fs::read_link(&name)?;
let builder = &mut FlatBufferBuilder::new();
let path_off = builder.create_string(path.to_str().unwrap());
let inner = msg::ReadlinkRes::create(
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()
},
))
let path_str = path.to_str().unwrap();
Ok(json!(path_str))
})
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct TruncateArgs {
promise_id: Option<u64>,
name: String,
len: u64,
}
pub fn op_truncate(
state: &ThreadSafeState,
base: &msg::Base<'_>,
data: Option<PinnedBuf>,
) -> CliOpResult {
assert!(data.is_none());
args: Value,
_zero_copy: Option<PinnedBuf>,
) -> Result<JsonOp, ErrBox> {
let args: TruncateArgs = serde_json::from_value(args)?;
let inner = base.inner_as_truncate().unwrap();
let (filename, filename_) = deno_fs::resolve_from_cwd(inner.name().unwrap())?;
let len = inner.len();
let (filename, filename_) = deno_fs::resolve_from_cwd(args.name.as_ref())?;
let len = args.len;
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);
let f = fs::OpenOptions::new().write(true).open(&filename)?;
f.set_len(u64::from(len))?;
Ok(empty_buf())
f.set_len(len)?;
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(
state: &ThreadSafeState,
base: &msg::Base<'_>,
data: Option<PinnedBuf>,
) -> CliOpResult {
assert!(data.is_none());
let base = Box::new(*base);
let inner = base.inner_as_make_temp_dir().unwrap();
let cmd_id = base.cmd_id();
args: Value,
_zero_copy: Option<PinnedBuf>,
) -> Result<JsonOp, ErrBox> {
let args: MakeTempDirArgs = serde_json::from_value(args)?;
// FIXME
state.check_write("make_temp")?;
let dir = inner.dir().map(PathBuf::from);
let prefix = inner.prefix().map(String::from);
let suffix = inner.suffix().map(String::from);
let dir = args.dir.map(PathBuf::from);
let prefix = args.prefix.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.
// See https://github.com/denoland/deno/issues/627.
// 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),
suffix.as_ref().map(|x| &**x),
)?;
let builder = &mut FlatBufferBuilder::new();
let path_off = builder.create_string(path.to_str().unwrap());
let inner = msg::MakeTempDirRes::create(
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()
},
))
let path_str = path.to_str().unwrap();
Ok(json!(path_str))
})
}
@ -482,24 +516,10 @@ pub fn op_utime(
pub fn op_cwd(
_state: &ThreadSafeState,
base: &msg::Base<'_>,
data: Option<PinnedBuf>,
) -> CliOpResult {
assert!(data.is_none());
let cmd_id = base.cmd_id();
_args: Value,
_zero_copy: Option<PinnedBuf>,
) -> Result<JsonOp, ErrBox> {
let path = std::env::current_dir()?;
let builder = &mut FlatBufferBuilder::new();
let cwd =
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)
let path_str = path.into_os_string().into_string().unwrap();
Ok(JsonOp::Sync(json!(path_str)))
}

View file

@ -26,7 +26,7 @@ mod workers;
// Warning! These values are duplicated in the TypeScript code (js/dispatch.ts),
// update with care.
pub const OP_FLATBUFFER: OpId = 44;
pub const OP_FLATBUFFER: OpId = 100;
pub const OP_READ: OpId = 1;
pub const OP_WRITE: OpId = 2;
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_STATUS: OpId = 40;
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(
state: &ThreadSafeState,
@ -242,6 +257,45 @@ pub fn dispatch(
OP_KILL => {
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),
_ => panic!("bad op_id"),
};

View file

@ -1,3 +1,4 @@
#![allow(dead_code)]
use crate::tokio_util;
use deno::Buf;
use deno::ErrBox;

View file

@ -1,15 +1,6 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers";
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];
}
import { sendSync, sendAsync } from "./dispatch_json";
import * as dispatch from "./dispatch";
/** Changes the permission of a specific file/directory of specified path
* synchronously.
@ -17,7 +8,7 @@ function req(
* Deno.chmodSync("/path/to/file", 0o666);
*/
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.
@ -25,5 +16,5 @@ export function chmodSync(path: string, mode: number): void {
* await Deno.chmod("/path/to/file", 0o666);
*/
export async function chmod(path: string, mode: number): Promise<void> {
await sendAsync(...req(path, mode));
await sendAsync(dispatch.OP_CHMOD, { path, mode });
}

View file

@ -1,16 +1,6 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers";
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];
}
import { sendSync, sendAsync } from "./dispatch_json";
import * as dispatch from "./dispatch";
/**
* 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
*/
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,
gid: number
): Promise<void> {
await sendAsync(...req(path, uid, gid));
await sendAsync(dispatch.OP_CHOWN, { path, uid, gid });
}

View file

@ -1,16 +1,6 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers";
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];
}
import { sendSync, sendAsync } from "./dispatch_json";
import * as dispatch from "./dispatch";
/** Copies the contents of a file to another by name synchronously.
* 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");
*/
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.
@ -36,5 +26,5 @@ export function copyFileSync(from: string, to: string): void {
* await Deno.copyFile("from.txt", "to.txt");
*/
export async function copyFile(from: string, to: string): Promise<void> {
await sendAsync(...req(from, to));
await sendAsync(dispatch.OP_COPY_FILE, { from, to });
}

View file

@ -1,6 +1,6 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
import { assert } from "./util";
import { sendSync, flatbuffers, msg } from "./dispatch_flatbuffers";
import { sendSync } from "./dispatch_json";
import * as dispatch from "./dispatch";
/**
* `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
*/
export function cwd(): string {
const builder = flatbuffers.createBuilder();
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()!;
return sendSync(dispatch.OP_CWD);
}
/**
@ -26,8 +18,5 @@ export function cwd(): string {
* throws `NotFound` exception if directory not available
*/
export function chdir(directory: string): void {
const builder = flatbuffers.createBuilder();
const directory_ = builder.createString(directory);
const inner = msg.Chdir.createChdir(builder, directory_);
sendSync(builder, msg.Any.Chdir, inner);
sendSync(dispatch.OP_CHDIR, { directory });
}

View file

@ -4,7 +4,7 @@ import * as flatbuffers from "./dispatch_flatbuffers";
import * as json from "./dispatch_json";
// 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_WRITE = 2;
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_STATUS = 40;
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 {
switch (opId) {
@ -73,6 +88,19 @@ export function asyncMsgFromRust(opId: number, ui8: Uint8Array): void {
case OP_HOST_GET_MESSAGE:
case OP_WORKER_GET_MESSAGE:
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);
break;
default:

View file

@ -1,5 +1,5 @@
// 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`,
* `statSync`, `lstatSync`.
@ -58,17 +58,17 @@ export class FileInfoImpl implements FileInfo {
name: string | null;
/* @internal */
constructor(private _inner: msg.StatRes) {
const modified = this._inner.modified().toFloat64();
const accessed = this._inner.accessed().toFloat64();
const created = this._inner.created().toFloat64();
const hasMode = this._inner.hasMode();
const mode = this._inner.mode(); // negative for invalid mode (Windows)
const name = this._inner.name();
constructor(private _res: StatResponse) {
const modified = this._res.modified;
const accessed = this._res.accessed;
const created = this._res.created;
const hasMode = this._res.hasMode;
const mode = this._res.mode; // negative for invalid mode (Windows)
const name = this._res.name;
this._isFile = this._inner.isFile();
this._isSymlink = this._inner.isSymlink();
this.len = this._inner.len().toFloat64();
this._isFile = this._res.isFile;
this._isSymlink = this._res.isSymlink;
this.len = this._res.len;
this.modified = modified ? modified : null;
this.accessed = accessed ? accessed : null;
this.created = created ? created : null;

View file

@ -1,23 +1,13 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers";
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];
}
import { sendSync, sendAsync } from "./dispatch_json";
import * as dispatch from "./dispatch";
/** Synchronously creates `newname` as a hard link to `oldname`.
*
* Deno.linkSync("old/name", "new/name");
*/
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`.
@ -25,5 +15,5 @@ export function linkSync(oldname: string, newname: string): void {
* await Deno.link("old/name", "new/name");
*/
export async function link(oldname: string, newname: string): Promise<void> {
await sendAsync(...req(oldname, newname));
await sendAsync(dispatch.OP_LINK, { oldname, newname });
}

View file

@ -1,6 +1,6 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers";
import { assert } from "./util";
import { sendSync, sendAsync } from "./dispatch_json";
import * as dispatch from "./dispatch";
export interface MakeTempDirOptions {
dir?: string;
@ -8,41 +8,13 @@ export interface MakeTempDirOptions {
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`.
*
* const tempDirName0 = Deno.makeTempDirSync();
* const tempDirName1 = Deno.makeTempDirSync({ prefix: 'my_temp' });
*/
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
@ -59,5 +31,5 @@ export function makeTempDirSync(options: MakeTempDirOptions = {}): string {
export async function makeTempDir(
options: MakeTempDirOptions = {}
): Promise<string> {
return res(await sendAsync(...req(options)));
return await sendAsync(dispatch.OP_MAKE_TEMP_DIR, options);
}

View file

@ -1,16 +1,6 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers";
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];
}
import { sendSync, sendAsync } from "./dispatch_json";
import * as dispatch from "./dispatch";
/** Creates a new directory with the specified path synchronously.
* If `recursive` is set to true, nested directories will be created (also known
@ -22,7 +12,7 @@ function req(
* Deno.mkdirSync("nested/directories", true);
*/
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.
@ -39,5 +29,5 @@ export async function mkdir(
recursive = false,
mode = 0o777
): Promise<void> {
await sendAsync(...req(path, recursive, mode));
await sendAsync(dispatch.OP_MKDIR, { path, recursive, mode });
}

View file

@ -1,25 +1,19 @@
// 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 { assert } from "./util";
import { StatResponse } from "./stat";
function req(path: string): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
const path_ = builder.createString(path);
const inner = msg.ReadDir.createReadDir(builder, path_);
return [builder, msg.Any.ReadDir, inner];
interface ReadDirResponse {
entries: StatResponse[];
}
function res(baseRes: null | msg.Base): FileInfo[] {
assert(baseRes != null);
assert(msg.Any.ReadDirRes === baseRes!.innerType());
const res = new msg.ReadDirRes();
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;
function res(response: ReadDirResponse): FileInfo[] {
return response.entries.map(
(statRes: StatResponse): FileInfo => {
return new FileInfoImpl(statRes);
}
);
}
/** 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("/");
*/
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.
@ -36,5 +30,5 @@ export function readDirSync(path: string): FileInfo[] {
* const files = await Deno.readDir("/");
*/
export async function readDir(path: string): Promise<FileInfo[]> {
return res(await sendAsync(...req(path)));
return res(await sendAsync(dispatch.OP_READ_DIR, { path }));
}

View file

@ -1,30 +1,13 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
import { assert } from "./util";
import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers";
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!;
}
import { sendSync, sendAsync } from "./dispatch_json";
import * as dispatch from "./dispatch";
/** Returns the destination of the named symbolic link synchronously.
*
* const targetPath = Deno.readlinkSync("symlink/path");
*/
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.
@ -32,5 +15,5 @@ export function readlinkSync(name: string): string {
* const targetPath = await Deno.readlink("symlink/path");
*/
export async function readlink(name: string): Promise<string> {
return res(await sendAsync(...req(name)));
return await sendAsync(dispatch.OP_READ_LINK, { name });
}

View file

@ -1,20 +1,11 @@
// 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 {
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
* error if permission denied, not found, or directory not empty if `recursive`
* set to false.
@ -23,7 +14,7 @@ function req(
* Deno.removeSync("/path/to/dir/or/file", {recursive: false});
*/
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
@ -37,5 +28,5 @@ export async function remove(
path: string,
options: RemoveOption = {}
): Promise<void> {
await sendAsync(...req(path, options));
await sendAsync(dispatch.OP_REMOVE, { path, recursive: !!options.recursive });
}

View file

@ -1,16 +1,6 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers";
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];
}
import { sendSync, sendAsync } from "./dispatch_json";
import * as dispatch from "./dispatch";
/** Synchronously renames (moves) `oldpath` to `newpath`. If `newpath` already
* exists and is not a directory, `renameSync()` replaces it. OS-specific
@ -20,7 +10,7 @@ function req(
* Deno.renameSync("old/path", "new/path");
*/
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
@ -30,5 +20,5 @@ export function renameSync(oldpath: string, newpath: string): void {
* await Deno.rename("old/path", "new/path");
*/
export async function rename(oldpath: string, newpath: string): Promise<void> {
await sendAsync(...req(oldpath, newpath));
await sendAsync(dispatch.OP_RENAME, { oldpath, newpath });
}

View file

@ -1,24 +1,18 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers";
import { assert } from "./util";
import { sendSync, sendAsync } from "./dispatch_json";
import * as dispatch from "./dispatch";
import { FileInfo, FileInfoImpl } from "./file_info";
function req(
filename: string,
lstat: boolean
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
const filename_ = builder.createString(filename);
const inner = msg.Stat.createStat(builder, filename_, lstat);
return [builder, msg.Any.Stat, inner];
}
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);
export interface StatResponse {
isFile: boolean;
isSymlink: boolean;
len: number;
modified: number;
accessed: number;
created: number;
mode: number;
hasMode: boolean; // false on windows
name: string | null;
}
/** 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());
*/
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.
@ -39,7 +37,11 @@ export async function lstat(filename: string): Promise<FileInfo> {
* assert(fileInfo.isFile());
*/
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
@ -49,7 +51,11 @@ export function lstatSync(filename: string): FileInfo {
* assert(fileInfo.isFile());
*/
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.
@ -59,5 +65,9 @@ export async function stat(filename: string): Promise<FileInfo> {
* assert(fileInfo.isFile());
*/
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);
}

View file

@ -1,23 +1,9 @@
// 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 { 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
* argument can be set to `dir` or `file` and is only available on Windows
* (ignored on other platforms).
@ -29,7 +15,10 @@ export function symlinkSync(
newname: string,
type?: string
): 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
@ -43,5 +32,8 @@ export async function symlink(
newname: string,
type?: string
): Promise<void> {
await sendAsync(...req(oldname, newname, type));
if (platform.os === "win" && type) {
return util.notImplemented();
}
await sendAsync(dispatch.OP_SYMLINK, { oldname, newname });
}

View file

@ -1,15 +1,17 @@
// 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(
name: string,
len?: number
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
const builder = flatbuffers.createBuilder();
const name_ = builder.createString(name);
len = len && len > 0 ? Math.floor(len) : 0;
const inner = msg.Truncate.createTruncate(builder, name_, len);
return [builder, msg.Any.Truncate, inner];
function coerceLen(len?: number): number {
if (!len) {
return 0;
}
if (len < 0) {
return 0;
}
return len;
}
/** Truncates or extends the specified file synchronously, updating the size of
@ -18,7 +20,7 @@ function req(
* Deno.truncateSync("hello.txt", 10);
*/
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);
*/
export async function truncate(name: string, len?: number): Promise<void> {
await sendAsync(...req(name, len));
await sendAsync(dispatch.OP_TRUNCATE, { name, len: coerceLen(len) });
}