mirror of
https://github.com/denoland/deno.git
synced 2024-12-25 08:39:09 -05:00
port fs ops to JSON (#2812)
This commit is contained in:
parent
520f9631e0
commit
a6f6209f52
21 changed files with 480 additions and 637 deletions
114
cli/msg.fbs
114
cli/msg.fbs
|
@ -1,27 +1,7 @@
|
|||
union Any {
|
||||
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().
|
||||
|
|
|
@ -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,
|
||||
|
|
526
cli/ops/fs.rs
526
cli/ops/fs.rs
|
@ -1,14 +1,12 @@
|
|||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||
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)))
|
||||
}
|
||||
|
|
|
@ -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"),
|
||||
};
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#![allow(dead_code)]
|
||||
use crate::tokio_util;
|
||||
use deno::Buf;
|
||||
use deno::ErrBox;
|
||||
|
|
17
js/chmod.ts
17
js/chmod.ts
|
@ -1,15 +1,6 @@
|
|||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||
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 });
|
||||
}
|
||||
|
|
18
js/chown.ts
18
js/chown.ts
|
@ -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 });
|
||||
}
|
||||
|
|
|
@ -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 });
|
||||
}
|
||||
|
|
19
js/dir.ts
19
js/dir.ts
|
@ -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 });
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
18
js/link.ts
18
js/link.ts
|
@ -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 });
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
18
js/mkdir.ts
18
js/mkdir.ts
|
@ -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 });
|
||||
}
|
||||
|
|
|
@ -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 }));
|
||||
}
|
||||
|
|
|
@ -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 });
|
||||
}
|
||||
|
|
17
js/remove.ts
17
js/remove.ts
|
@ -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 });
|
||||
}
|
||||
|
|
18
js/rename.ts
18
js/rename.ts
|
@ -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 });
|
||||
}
|
||||
|
|
54
js/stat.ts
54
js/stat.ts
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 });
|
||||
}
|
||||
|
|
|
@ -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) });
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue