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

Crystal runtime crashes on closed file descriptor for STDIN #14569

Open
straight-shoota opened this issue May 6, 2024 · 3 comments
Open

Crystal runtime crashes on closed file descriptor for STDIN #14569

straight-shoota opened this issue May 6, 2024 · 3 comments

Comments

@straight-shoota
Copy link
Member

straight-shoota commented May 6, 2024

As part of programm startup, the Crystal runtime initializes handles for the three standard streams.
If such a stream is already closed, the runtime crashes.

This affects any Crystal program which uses STDIN somehow (i.e. the constant is initialized).

A minimal reproduction is crystal <&- (the shell redirection <&- instructs that stdin is to be closed). This results in the following error:

Unhandled exception: Unable to get info: Bad file descriptor (IO::Error)
  from /opt/homebrew/Cellar/crystal/1.12.1_1/bin/crystal in 'raise<IO::Error>:NoReturn'
  from /opt/homebrew/Cellar/crystal/1.12.1_1/bin/crystal in 'Crystal::System::FileDescriptor::system_info<Int32>:File::Info'
  from /opt/homebrew/Cellar/crystal/1.12.1_1/bin/crystal in 'IO::FileDescriptor::new<Int32>:IO::FileDescriptor'
  from /opt/homebrew/Cellar/crystal/1.12.1_1/bin/crystal in 'IO::FileDescriptor::from_stdio<Int32>:IO::FileDescriptor'
  from /opt/homebrew/Cellar/crystal/1.12.1_1/bin/crystal in '__crystal_main'
  from /opt/homebrew/Cellar/crystal/1.12.1_1/bin/crystal in 'main'

The same error does not appear when passing a closed output file descriptor (crystal >&-).

I'm not sure how to reproduce in pure Crystal yet. Passing a closed IO to Process.run errors on the invoking process (Closed stream from Process#copy_io). This needs to be fixed as well.

stdin = IO::Memory.new
stdin.close
Process.run("crystal", input: stdin, output: :inherit, error: :inherit)

This was originally reported in https://forum.crystal-lang.org/t/unable-to-get-info-bad-file-descriptor-io-error/6820

@straight-shoota
Copy link
Member Author

straight-shoota commented May 6, 2024

Interestingly, Process::Redirect::Close does not actually close the file descriptor. It only passes the null device (i.e. its equivalent to crystal < /dev/null).
A closed file descriptor equivalent to the shell redirection apparently <&- has different semantics.

@crysbot
Copy link

crysbot commented May 6, 2024

This issue has been mentioned on Crystal Forum. There might be relevant details there:

https://forum.crystal-lang.org/t/unable-to-get-info-bad-file-descriptor-io-error/6820/4

@crysbot
Copy link

crysbot commented May 7, 2024

This issue has been mentioned on Crystal Forum. There might be relevant details there:

https://forum.crystal-lang.org/t/unable-to-get-info-bad-file-descriptor-io-error/6820/12

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants