diff options
Diffstat (limited to 'cli')
-rw-r--r-- | cli/msg.fbs | 3 | ||||
-rw-r--r-- | cli/ops.rs | 24 | ||||
-rw-r--r-- | cli/resources.rs | 91 |
3 files changed, 71 insertions, 47 deletions
diff --git a/cli/msg.fbs b/cli/msg.fbs index d76e70d85..82a3d573d 100644 --- a/cli/msg.fbs +++ b/cli/msg.fbs @@ -538,6 +538,9 @@ table Run { stdin: ProcessStdio; stdout: ProcessStdio; stderr: ProcessStdio; + stdin_rid: uint32; + stdout_rid: uint32; + stderr_rid: uint32; } table RunRes { diff --git a/cli/ops.rs b/cli/ops.rs index d4add61e0..e4448c3b5 100644 --- a/cli/ops.rs +++ b/cli/ops.rs @@ -1793,9 +1793,27 @@ fn op_run( c.env(entry.key().unwrap(), entry.value().unwrap()); }); - c.stdin(subprocess_stdio_map(inner.stdin())); - c.stdout(subprocess_stdio_map(inner.stdout())); - c.stderr(subprocess_stdio_map(inner.stderr())); + // TODO: make this work with other resources, eg. sockets + let stdin_rid = inner.stdin_rid(); + if stdin_rid > 0 { + c.stdin(resources::get_file(stdin_rid)?); + } else { + c.stdin(subprocess_stdio_map(inner.stdin())); + } + + let stdout_rid = inner.stdout_rid(); + if stdout_rid > 0 { + c.stdout(resources::get_file(stdout_rid)?); + } else { + c.stdout(subprocess_stdio_map(inner.stdout())); + } + + let stderr_rid = inner.stderr_rid(); + if stderr_rid > 0 { + c.stderr(resources::get_file(stderr_rid)?); + } else { + c.stderr(subprocess_stdio_map(inner.stderr())); + } // Spawn the command. let child = c.spawn_async().map_err(DenoError::from)?; diff --git a/cli/resources.rs b/cli/resources.rs index e98327b63..13fd8f6fe 100644 --- a/cli/resources.rs +++ b/cli/resources.rs @@ -492,29 +492,19 @@ pub fn get_repl(rid: ResourceId) -> DenoResult<Arc<Mutex<Repl>>> { } } -pub fn lookup(rid: ResourceId) -> Option<Resource> { - debug!("resource lookup {}", rid); - let table = RESOURCE_TABLE.lock().unwrap(); - table.get(&rid).map(|_| Resource { rid }) -} - -// TODO(kevinkassimo): revamp this after the following lands: +// TODO: revamp this after the following lands: // https://github.com/tokio-rs/tokio/pull/785 -pub fn seek( - resource: Resource, - offset: i32, - whence: u32, -) -> Box<dyn Future<Item = (), Error = DenoError> + Send> { +pub fn get_file(rid: ResourceId) -> DenoResult<std::fs::File> { let mut table = RESOURCE_TABLE.lock().unwrap(); // We take ownership of File here. // It is put back below while still holding the lock. - let maybe_repr = table.remove(&resource.rid); + let maybe_repr = table.remove(&rid); + match maybe_repr { - None => panic!("bad rid"), - Some(Repr::FsFile(f)) => { + Some(Repr::FsFile(r)) => { // Trait Clone not implemented on tokio::fs::File, // so convert to std File first. - let std_file = f.into_std(); + let std_file = r.into_std(); // Create a copy and immediately put back. // We don't want to block other resource ops. // try_clone() would yield a copy containing the same @@ -523,36 +513,49 @@ pub fn seek( // to write back. let maybe_std_file_copy = std_file.try_clone(); // Insert the entry back with the same rid. - table.insert( - resource.rid, - Repr::FsFile(tokio_fs::File::from_std(std_file)), - ); - // Translate seek mode to Rust repr. - let seek_from = match whence { - 0 => SeekFrom::Start(offset as u64), - 1 => SeekFrom::Current(i64::from(offset)), - 2 => SeekFrom::End(i64::from(offset)), - _ => { - return Box::new(futures::future::err(deno_error::new( - deno_error::ErrorKind::InvalidSeekMode, - format!("Invalid seek mode: {}", whence), - ))); - } - }; + table.insert(rid, Repr::FsFile(tokio_fs::File::from_std(std_file))); + if maybe_std_file_copy.is_err() { - return Box::new(futures::future::err(DenoError::from( - maybe_std_file_copy.unwrap_err(), - ))); + return Err(DenoError::from(maybe_std_file_copy.unwrap_err())); } - let mut std_file_copy = maybe_std_file_copy.unwrap(); - Box::new(futures::future::lazy(move || { - let result = std_file_copy - .seek(seek_from) - .map(|_| {}) - .map_err(DenoError::from); - futures::future::result(result) - })) + + let std_file_copy = maybe_std_file_copy.unwrap(); + + Ok(std_file_copy) } - _ => panic!("cannot seek"), + _ => Err(bad_resource()), + } +} + +pub fn lookup(rid: ResourceId) -> Option<Resource> { + debug!("resource lookup {}", rid); + let table = RESOURCE_TABLE.lock().unwrap(); + table.get(&rid).map(|_| Resource { rid }) +} + +pub fn seek( + resource: Resource, + offset: i32, + whence: u32, +) -> Box<dyn Future<Item = (), Error = DenoError> + Send> { + // Translate seek mode to Rust repr. + let seek_from = match whence { + 0 => SeekFrom::Start(offset as u64), + 1 => SeekFrom::Current(i64::from(offset)), + 2 => SeekFrom::End(i64::from(offset)), + _ => { + return Box::new(futures::future::err(deno_error::new( + deno_error::ErrorKind::InvalidSeekMode, + format!("Invalid seek mode: {}", whence), + ))); + } + }; + + match get_file(resource.rid) { + Ok(mut file) => Box::new(futures::future::lazy(move || { + let result = file.seek(seek_from).map(|_| {}).map_err(DenoError::from); + futures::future::result(result) + })), + Err(err) => Box::new(futures::future::err(err)), } } |