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:
parent
69be1f3cf7
commit
b65d5024ef
6 changed files with 29 additions and 17 deletions
|
@ -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())],
|
||||||
|
});
|
||||||
|
|
1
cli/tests/testdata/task/deno.json
vendored
1
cli/tests/testdata/task/deno.json
vendored
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
2
cli/tests/testdata/task/task_no_args.out
vendored
2
cli/tests/testdata/task/task_no_args.out
vendored
|
@ -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\")"
|
||||||
|
|
|
@ -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\")"
|
||||||
|
|
3
cli/tests/testdata/task/task_piped_stdin.out
vendored
Normal file
3
cli/tests/testdata/task/task_piped_stdin.out
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[WILDCARD]
|
||||||
|
Uint8Array(1) [ 49 ]
|
||||||
|
Uint8Array(1) [ 50 ]
|
|
@ -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()))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue