Inconsistent behavior of `stdio[3]: 'ignore'`
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 122k
- Forks
- 37.3k
- Avg merge
- 4d 2h
- Merged PRs (30d)
- 283
Description
Version
v21.7.2
Platform
Linux my-laptop 6.5.0-26-generic #26-Ubuntu SMP PREEMPT_DYNAMIC Tue Mar 5 21:19:28 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
Subsystem
child_process
What steps will reproduce the bug?
With print.js:
import {writeSync} from 'node:fs'
const fdNumber = Number(process.argv[2])
writeSync(fdNumber, '.')
With example.js:
import {spawn} from 'node:child_process'
spawn('node', ['./print.js', '1'], {stdio: ['pipe', 'ignore', 'inherit', 'ignore']})
Prints nothing. But:
import {spawn} from 'node:child_process'
spawn('node', ['./print.js', '3'], {stdio: ['pipe', 'ignore', 'inherit', 'ignore']})
Prints the following:
node:fs:933
handleErrorFromBinding(ctx);
^
Error: EINVAL: invalid argument, write
at writeSync (node:fs:933:3)
at file:///home/ether/Desktop/print.js:4:1
at ModuleJob.run (node:internal/modules/esm/module_job:222:25)
at async ModuleLoader.import (node:internal/modules/esm/loader:323:24)
at async loadESM (node:internal/process/esm_loader:28:7)
at async handleMainPromise (node:internal/modules/run_main:120:12) {
errno: -22,
syscall: 'write',
code: 'EINVAL'
}
Node.js v21.7.2
How often does it reproduce? Is there a required condition?
No.
What is the expected behavior? Why is that the expected behavior?
ignore should behave consistently regardless of the same descriptor.
What do you see instead?
ignore's behavior differs between stdio[1] and stdio[3].
Additional information
I understand the reason might be that child processes should always have a stdin/stdout/stderr even when ignored, while this does not apply to other file descriptors. So stdio[3]: 'ignore' probably results in no file descriptor being created, as opposed to stdio[1]: 'ignore'.
On one hand, the current behavior is more efficient, as it does not waste creating a file descriptor that's not going to be used.
On the other hand, this results in inconsistent behavior.
Any change there would be breaking too. So this probably won't be fixed, but I reported it in case this was not intentional.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Run the reproduction from print.js and example.js to confirm the difference between stdio[1] and stdio[3]. Then inspect the child_process implementation and related tests to determine whether the descriptor behavior is intentional. Done means the behavior is either made consistent with coverage or its documented, compatibility-sensitive rationale is established.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js
- Domain
- backend, operating-systems
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100