1
0
Fork 0
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:
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 { 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().

View file

@ -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,

View file

@ -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)
} }

View file

@ -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"),
}; };

View file

@ -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;

View file

@ -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 });
} }

View file

@ -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 });
} }

View file

@ -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 });
} }

View file

@ -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);
} }

View file

@ -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:

View file

@ -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;

View file

@ -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 });
} }

View file

@ -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);
} }

View file

@ -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 });
} }

View file

@ -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 }));
} }

View file

@ -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 });
} }

View file

@ -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 });
} }

View file

@ -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 });
} }

View file

@ -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);
} }

View file

@ -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 });
} }

View file

@ -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) });
} }