Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent behavior of stdio[3]: 'ignore' #52422

Open
ehmicky opened this issue Apr 8, 2024 · 4 comments
Open

Inconsistent behavior of stdio[3]: 'ignore' #52422

ehmicky opened this issue Apr 8, 2024 · 4 comments
Labels
child_process Issues and PRs related to the child_process subsystem.

Comments

@ehmicky
Copy link

ehmicky commented Apr 8, 2024

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.

@VoltrexKeyva VoltrexKeyva added the child_process Issues and PRs related to the child_process subsystem. label Apr 8, 2024
@mertcanaltin
Copy link
Member

I experienced this when I was examining

➜  node git:(main) ✗ node example.js
node:internal/fs/utils:356
    throw err;
    ^

Error: ENXIO: no such device or address, write
    at writeSync (node:fs:933:3)
    at Object.<anonymous> (/Users/mert/Desktop/openSource/node/print.js:4:1)
    at Module._compile (node:internal/modules/cjs/loader:1368:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1426:10)
    at Module.load (node:internal/modules/cjs/loader:1205:32)
    at Module._load (node:internal/modules/cjs/loader:1021:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:142:12)
    at node:internal/main/run_main_module:28:49 {
  errno: -6,
  syscall: 'write',
  code: 'ENXIO'
}

Node.js v21.7.2
Darwin J4YJY6LC7W 23.3.0 Darwin Kernel Version 23.3.0: Wed Dec 20 21:30:44 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T6000 arm64 ```

@ehmicky
Copy link
Author

ehmicky commented Apr 9, 2024

The error code is different on different OS:

  • EINVAL on Linux
  • ENXIO on macOS
  • EBADF on Windows

But that might not be a problem? I am guessing retrieving the file descriptor is using a syscall, i.e. translates to different error codes.

@mertcanaltin
Copy link
Member

mertcanaltin commented Apr 9, 2024

The error code is different on different OS:

  • EINVAL on Linux

  • ENXIO on macOS

  • EBADF on Windows

But that might not be a problem? I am guessing retrieving the file descriptor is using a syscall, i.e. translates to different error codes.

I just did 4 and got an EBADF code @ehmicky

ENXIO as detail: Indicates that there is no such device or address

@mertcanaltin
Copy link
Member

['./print.js', '1'] and ['./print.js', '3'] both of them are getting to this stage

self.emit('spawn');

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
child_process Issues and PRs related to the child_process subsystem.
Projects
None yet
Development

No branches or pull requests

3 participants