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())],
|
||||
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",
|
||||
"deno_echo": "deno eval 'console.log(5)'",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
|
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
|
||||
- exit_code_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
|
||||
deno run main.ts && deno eval "console.log(\"test\")"
|
||||
|
|
|
@ -9,5 +9,7 @@ Available tasks:
|
|||
echo 1
|
||||
- exit_code_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
|
||||
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;
|
||||
t.add(StdFileResource::stdio(
|
||||
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),
|
||||
},
|
||||
"stdin",
|
||||
|
@ -296,14 +298,14 @@ impl Resource for ChildStderrResource {
|
|||
|
||||
#[derive(Clone)]
|
||||
enum StdFileResourceInner {
|
||||
File(Arc<Mutex<StdFile>>),
|
||||
Stdin(Arc<Mutex<StdFile>>),
|
||||
// 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
|
||||
// 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
|
||||
Stdin,
|
||||
Stdout,
|
||||
Stderr,
|
||||
File(Arc<Mutex<StdFile>>),
|
||||
}
|
||||
|
||||
impl StdFileResourceInner {
|
||||
|
@ -313,13 +315,12 @@ impl StdFileResourceInner {
|
|||
|
||||
pub fn with_file<R>(&self, mut f: impl FnMut(&mut StdFile) -> R) -> R {
|
||||
match self {
|
||||
Self::Stdin => f(&mut STDIN_HANDLE.try_clone().unwrap()),
|
||||
Self::Stdout => f(&mut STDOUT_HANDLE.try_clone().unwrap()),
|
||||
Self::Stderr => f(&mut STDERR_HANDLE.try_clone().unwrap()),
|
||||
Self::File(file) => {
|
||||
Self::File(file) | Self::Stdin(file) => {
|
||||
let mut file = file.lock();
|
||||
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 {
|
||||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||
match self {
|
||||
Self::File(file) | Self::Stdin(file) => file.lock().read(buf),
|
||||
Self::Stdout => 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 {
|
||||
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
||||
match self {
|
||||
Self::File(file) => file.lock().write(buf),
|
||||
Self::Stdin(_) => Err(ErrorKind::Unsupported.into()),
|
||||
Self::Stdout => std::io::stdout().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<()> {
|
||||
match self {
|
||||
Self::File(file) => file.lock().flush(),
|
||||
Self::Stdin(_) => Err(ErrorKind::Unsupported.into()),
|
||||
Self::Stdout => std::io::stdout().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>> {
|
||||
match &self.inner {
|
||||
StdFileResourceInner::File(fs_file) => fs_file.clone(),
|
||||
StdFileResourceInner::Stdin => {
|
||||
Arc::new(Mutex::new(STDIN_HANDLE.try_clone().unwrap()))
|
||||
}
|
||||
StdFileResourceInner::File(fs_file)
|
||||
| StdFileResourceInner::Stdin(fs_file) => fs_file.clone(),
|
||||
StdFileResourceInner::Stdout => {
|
||||
Arc::new(Mutex::new(STDOUT_HANDLE.try_clone().unwrap()))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue