summaryrefslogtreecommitdiff
path: root/cli/ops/files.rs
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2019-08-14 17:03:02 +0200
committerRyan Dahl <ry@tinyclouds.org>2019-08-14 11:03:02 -0400
commite6c349af9f7260c2c4ec713bd231fe554240721e (patch)
tree7671dabb8270cc0c2d7f7f5a3b5f5d8d4b1e0986 /cli/ops/files.rs
parent58f0e9b9b1b53ca486ef38ae662b98cbde839248 (diff)
split up ops.rs (#2753)
Note cli/dispatch_minimal.rs ops are not yet included in cli/ops. This is part of work towards #2730
Diffstat (limited to 'cli/ops/files.rs')
-rw-r--r--cli/ops/files.rs231
1 files changed, 231 insertions, 0 deletions
diff --git a/cli/ops/files.rs b/cli/ops/files.rs
new file mode 100644
index 000000000..ce3285623
--- /dev/null
+++ b/cli/ops/files.rs
@@ -0,0 +1,231 @@
+// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
+use crate::deno_error;
+use crate::fs as deno_fs;
+use crate::msg;
+use crate::ops::empty_buf;
+use crate::ops::ok_buf;
+use crate::ops::serialize_response;
+use crate::ops::CliOpResult;
+use crate::resources;
+use crate::state::ThreadSafeState;
+use crate::tokio_write;
+use deno::*;
+use flatbuffers::FlatBufferBuilder;
+use futures::Future;
+use std;
+use std::convert::From;
+use tokio;
+
+pub fn op_open(
+ state: &ThreadSafeState,
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let cmd_id = base.cmd_id();
+ let inner = base.inner_as_open().unwrap();
+ let (filename, filename_) =
+ deno_fs::resolve_from_cwd(inner.filename().unwrap())?;
+ let mode = inner.mode().unwrap();
+
+ let mut open_options = tokio::fs::OpenOptions::new();
+
+ match mode {
+ "r" => {
+ open_options.read(true);
+ }
+ "r+" => {
+ open_options.read(true).write(true);
+ }
+ "w" => {
+ open_options.create(true).write(true).truncate(true);
+ }
+ "w+" => {
+ open_options
+ .read(true)
+ .create(true)
+ .write(true)
+ .truncate(true);
+ }
+ "a" => {
+ open_options.create(true).append(true);
+ }
+ "a+" => {
+ open_options.read(true).create(true).append(true);
+ }
+ "x" => {
+ open_options.create_new(true).write(true);
+ }
+ "x+" => {
+ open_options.create_new(true).read(true).write(true);
+ }
+ &_ => {
+ panic!("Unknown file open mode.");
+ }
+ }
+
+ match mode {
+ "r" => {
+ state.check_read(&filename_)?;
+ }
+ "w" | "a" | "x" => {
+ state.check_write(&filename_)?;
+ }
+ &_ => {
+ state.check_read(&filename_)?;
+ state.check_write(&filename_)?;
+ }
+ }
+
+ let op = open_options.open(filename).map_err(ErrBox::from).and_then(
+ move |fs_file| {
+ let resource = resources::add_fs_file(fs_file);
+ let builder = &mut FlatBufferBuilder::new();
+ let inner =
+ msg::OpenRes::create(builder, &msg::OpenResArgs { rid: resource.rid });
+ Ok(serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ inner: Some(inner.as_union_value()),
+ inner_type: msg::Any::OpenRes,
+ ..Default::default()
+ },
+ ))
+ },
+ );
+ if base.sync() {
+ let buf = op.wait()?;
+ Ok(Op::Sync(buf))
+ } else {
+ Ok(Op::Async(Box::new(op)))
+ }
+}
+
+pub fn op_close(
+ _state: &ThreadSafeState,
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let inner = base.inner_as_close().unwrap();
+ let rid = inner.rid();
+ match resources::lookup(rid) {
+ None => Err(deno_error::bad_resource()),
+ Some(resource) => {
+ resource.close();
+ ok_buf(empty_buf())
+ }
+ }
+}
+
+pub fn op_read(
+ _state: &ThreadSafeState,
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ let cmd_id = base.cmd_id();
+ let inner = base.inner_as_read().unwrap();
+ let rid = inner.rid();
+
+ match resources::lookup(rid) {
+ None => Err(deno_error::bad_resource()),
+ Some(resource) => {
+ let op = tokio::io::read(resource, data.unwrap())
+ .map_err(ErrBox::from)
+ .and_then(move |(_resource, _buf, nread)| {
+ let builder = &mut FlatBufferBuilder::new();
+ let inner = msg::ReadRes::create(
+ builder,
+ &msg::ReadResArgs {
+ nread: nread as u32,
+ eof: nread == 0,
+ },
+ );
+ Ok(serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ inner: Some(inner.as_union_value()),
+ inner_type: msg::Any::ReadRes,
+ ..Default::default()
+ },
+ ))
+ });
+ if base.sync() {
+ let buf = op.wait()?;
+ Ok(Op::Sync(buf))
+ } else {
+ Ok(Op::Async(Box::new(op)))
+ }
+ }
+ }
+}
+
+pub fn op_write(
+ _state: &ThreadSafeState,
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ let cmd_id = base.cmd_id();
+ let inner = base.inner_as_write().unwrap();
+ let rid = inner.rid();
+
+ match resources::lookup(rid) {
+ None => Err(deno_error::bad_resource()),
+ Some(resource) => {
+ let op = tokio_write::write(resource, data.unwrap())
+ .map_err(ErrBox::from)
+ .and_then(move |(_resource, _buf, nwritten)| {
+ let builder = &mut FlatBufferBuilder::new();
+ let inner = msg::WriteRes::create(
+ builder,
+ &msg::WriteResArgs {
+ nbyte: nwritten as u32,
+ },
+ );
+ Ok(serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ inner: Some(inner.as_union_value()),
+ inner_type: msg::Any::WriteRes,
+ ..Default::default()
+ },
+ ))
+ });
+ if base.sync() {
+ let buf = op.wait()?;
+ Ok(Op::Sync(buf))
+ } else {
+ Ok(Op::Async(Box::new(op)))
+ }
+ }
+ }
+}
+
+pub fn op_seek(
+ _state: &ThreadSafeState,
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let inner = base.inner_as_seek().unwrap();
+ let rid = inner.rid();
+ let offset = inner.offset();
+ let whence = inner.whence();
+
+ match resources::lookup(rid) {
+ None => Err(deno_error::bad_resource()),
+ Some(resource) => {
+ let op = resources::seek(resource, offset, whence)
+ .and_then(move |_| Ok(empty_buf()));
+ if base.sync() {
+ let buf = op.wait()?;
+ Ok(Op::Sync(buf))
+ } else {
+ Ok(Op::Async(Box::new(op)))
+ }
+ }
+ }
+}