1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-23 15:49:44 -05:00

fix: read raw stdin to prevent buffering (regression) (#14704)

This commit is contained in:
David Sherret 2022-05-23 12:35:02 -04:00 committed by GitHub
parent 69be1f3cf7
commit b65d5024ef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 29 additions and 17 deletions

View file

@ -85,3 +85,9 @@ itest!(task_deno_exe_no_env {
envs: vec![("NO_COLOR".to_string(), "1".to_string())], envs: vec![("NO_COLOR".to_string(), "1".to_string())],
env_clear: true, env_clear: true,
}); });
itest!(task_piped_stdin {
args_vec: vec!["task", "-q", "--config", "task/deno.json", "piped"],
output: "task/task_piped_stdin.out",
envs: vec![("NO_COLOR".to_string(), "1".to_string())],
});

View file

@ -4,6 +4,7 @@
"echo": "echo 1", "echo": "echo 1",
"deno_echo": "deno eval 'console.log(5)'", "deno_echo": "deno eval 'console.log(5)'",
"strings": "deno run main.ts && deno eval \"console.log(\\\"test\\\")\"", "strings": "deno run main.ts && deno eval \"console.log(\\\"test\\\")\"",
"piped": "echo 12345 | (deno eval 'const b = new Uint8Array(1);Deno.stdin.readSync(b);console.log(b)' && deno eval 'const b = new Uint8Array(1);Deno.stdin.readSync(b);console.log(b)')",
"exit_code_5": "echo $(echo 10 ; exit 2) && exit 5" "exit_code_5": "echo $(echo 10 ; exit 2) && exit 5"
} }
} }

View file

@ -7,5 +7,7 @@ Available tasks:
echo 1 echo 1
- exit_code_5 - exit_code_5
echo $(echo 10 ; exit 2) && exit 5 echo $(echo 10 ; exit 2) && exit 5
- piped
echo 12345 | (deno eval 'const b = new Uint8Array(1);Deno.stdin.readSync(b);console.log(b)' && deno eval 'const b = new Uint8Array(1);Deno.stdin.readSync(b);console.log(b)')
- strings - strings
deno run main.ts && deno eval "console.log(\"test\")" deno run main.ts && deno eval "console.log(\"test\")"

View file

@ -9,5 +9,7 @@ Available tasks:
echo 1 echo 1
- exit_code_5 - exit_code_5
echo $(echo 10 ; exit 2) && exit 5 echo $(echo 10 ; exit 2) && exit 5
- piped
echo 12345 | (deno eval 'const b = new Uint8Array(1);Deno.stdin.readSync(b);console.log(b)' && deno eval 'const b = new Uint8Array(1);Deno.stdin.readSync(b);console.log(b)')
- strings - strings
deno run main.ts && deno eval "console.log(\"test\")" deno run main.ts && deno eval "console.log(\"test\")"

View file

@ -0,0 +1,3 @@
[WILDCARD]
Uint8Array(1) [ 49 ]
Uint8Array(1) [ 50 ]

View file

@ -116,7 +116,9 @@ pub fn init_stdio(stdio: Stdio) -> Extension {
let t = &mut state.resource_table; let t = &mut state.resource_table;
t.add(StdFileResource::stdio( t.add(StdFileResource::stdio(
match stdio.stdin { match stdio.stdin {
StdioPipe::Inherit => StdFileResourceInner::Stdin, StdioPipe::Inherit => StdFileResourceInner::Stdin(Arc::new(
Mutex::new(STDIN_HANDLE.try_clone().unwrap()),
)),
StdioPipe::File(pipe) => StdFileResourceInner::file(pipe), StdioPipe::File(pipe) => StdFileResourceInner::file(pipe),
}, },
"stdin", "stdin",
@ -296,14 +298,14 @@ impl Resource for ChildStderrResource {
#[derive(Clone)] #[derive(Clone)]
enum StdFileResourceInner { enum StdFileResourceInner {
File(Arc<Mutex<StdFile>>),
Stdin(Arc<Mutex<StdFile>>),
// Ideally we would store stdio as an StdFile, but we get some Windows // Ideally we would store stdio as an StdFile, but we get some Windows
// specific functionality for free by using Rust std's wrappers. So we // specific functionality for free by using Rust std's wrappers. So we
// take a bit of a complexity hit here in order to not have to duplicate // take a bit of a complexity hit here in order to not have to duplicate
// the functionality in Rust's std/src/sys/windows/stdio.rs // the functionality in Rust's std/src/sys/windows/stdio.rs
Stdin,
Stdout, Stdout,
Stderr, Stderr,
File(Arc<Mutex<StdFile>>),
} }
impl StdFileResourceInner { impl StdFileResourceInner {
@ -313,13 +315,12 @@ impl StdFileResourceInner {
pub fn with_file<R>(&self, mut f: impl FnMut(&mut StdFile) -> R) -> R { pub fn with_file<R>(&self, mut f: impl FnMut(&mut StdFile) -> R) -> R {
match self { match self {
Self::Stdin => f(&mut STDIN_HANDLE.try_clone().unwrap()), Self::File(file) | Self::Stdin(file) => {
Self::Stdout => f(&mut STDOUT_HANDLE.try_clone().unwrap()),
Self::Stderr => f(&mut STDERR_HANDLE.try_clone().unwrap()),
Self::File(file) => {
let mut file = file.lock(); let mut file = file.lock();
f(&mut file) f(&mut file)
} }
Self::Stdout => f(&mut STDOUT_HANDLE.try_clone().unwrap()),
Self::Stderr => f(&mut STDERR_HANDLE.try_clone().unwrap()),
} }
} }
@ -344,10 +345,9 @@ impl StdFileResourceInner {
impl Read for StdFileResourceInner { impl Read for StdFileResourceInner {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> { fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
match self { match self {
Self::File(file) | Self::Stdin(file) => file.lock().read(buf),
Self::Stdout => Err(ErrorKind::Unsupported.into()), Self::Stdout => Err(ErrorKind::Unsupported.into()),
Self::Stderr => Err(ErrorKind::Unsupported.into()), Self::Stderr => Err(ErrorKind::Unsupported.into()),
Self::Stdin => std::io::stdin().read(buf),
Self::File(file) => file.lock().read(buf),
} }
} }
} }
@ -355,19 +355,19 @@ impl Read for StdFileResourceInner {
impl Write for StdFileResourceInner { impl Write for StdFileResourceInner {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> { fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
match self { match self {
Self::File(file) => file.lock().write(buf),
Self::Stdin(_) => Err(ErrorKind::Unsupported.into()),
Self::Stdout => std::io::stdout().write(buf), Self::Stdout => std::io::stdout().write(buf),
Self::Stderr => std::io::stderr().write(buf), Self::Stderr => std::io::stderr().write(buf),
Self::Stdin => Err(ErrorKind::Unsupported.into()),
Self::File(file) => file.lock().write(buf),
} }
} }
fn flush(&mut self) -> std::io::Result<()> { fn flush(&mut self) -> std::io::Result<()> {
match self { match self {
Self::File(file) => file.lock().flush(),
Self::Stdin(_) => Err(ErrorKind::Unsupported.into()),
Self::Stdout => std::io::stdout().flush(), Self::Stdout => std::io::stdout().flush(),
Self::Stderr => std::io::stderr().flush(), Self::Stderr => std::io::stderr().flush(),
Self::Stdin => Err(ErrorKind::Unsupported.into()),
Self::File(file) => file.lock().flush(),
} }
} }
} }
@ -397,10 +397,8 @@ impl StdFileResource {
pub fn std_file(&self) -> Arc<Mutex<StdFile>> { pub fn std_file(&self) -> Arc<Mutex<StdFile>> {
match &self.inner { match &self.inner {
StdFileResourceInner::File(fs_file) => fs_file.clone(), StdFileResourceInner::File(fs_file)
StdFileResourceInner::Stdin => { | StdFileResourceInner::Stdin(fs_file) => fs_file.clone(),
Arc::new(Mutex::new(STDIN_HANDLE.try_clone().unwrap()))
}
StdFileResourceInner::Stdout => { StdFileResourceInner::Stdout => {
Arc::new(Mutex::new(STDOUT_HANDLE.try_clone().unwrap())) Arc::new(Mutex::new(STDOUT_HANDLE.try_clone().unwrap()))
} }