Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/tty/screen.rb
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ def ioctl?(control, buf)
($stdout.ioctl(control, buf) >= 0) ||
($stdin.ioctl(control, buf) >= 0) ||
($stderr.ioctl(control, buf) >= 0)
rescue SystemCallError
rescue SystemCallError, NoMethodError
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intention behind the ioctl? method isn't to check whether ioctl is supported. It assumes it is, and it checks whether any ioctl call on the standard streams can read information. So that's why only SystemCallError is being caught. Catching NoMethodError seems out of context here and confusing.

I believe a better approach and more direct would be to add the check in the size_from_ioctl method. That's what already happens at the module level.

def size_from_ioctl
  return unless output.respond_to?(:ioctl)
  ...
end

false
end
module_function :ioctl?
Expand Down
9 changes: 9 additions & 0 deletions spec/unit/screen_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,15 @@ def ioctl(_control, buf)
end
end

it "doesn't detect size if the output doesn't respond to #iotcl" do
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test description isn't strictly correct. At the module level, there is a check to see whether output supports ioctl, failing that, it inlines the size_from_ioctl method body with nil implementation. The issue here is the runtime swapping of the output stream.

Suggested change
it "doesn't detect size if the output doesn't respond to #iotcl" do
it "doesn't detect size if the output changes to non-ioctl at runtime" do

output = double(:output, write: nil)
allow(output).to receive(:ioctl).and_raise(NoMethodError)

replace_standard_streams(output) do
expect(screen.size_from_ioctl).to eq(nil)
end
end

it "detects no columns" do
allow(screen).to receive(:ioctl?).and_return(true)

Expand Down
Loading