Skip to content

Commit

Permalink
Try to open stdio in non-blocking mode (#8787)
Browse files Browse the repository at this point in the history
* Try to open stdio in non-blocking mode

* Some code style changes suggested by @Sija
  • Loading branch information
waj committed Feb 12, 2020
1 parent a2bba01 commit 9c30c26
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 8 deletions.
16 changes: 11 additions & 5 deletions spec/spec_helper.cr
Expand Up @@ -256,7 +256,7 @@ def run(code, filename = nil, inject_primitives = true, debug = Crystal::Debug::
end
end

def build_and_run(code)
def build(code)
code_file = File.tempname("build_and_run_code")

# write code to the temp file
Expand All @@ -267,15 +267,21 @@ def build_and_run(code)
`bin/crystal build #{encode_program_flags} #{code_file.path.inspect} -o #{binary_file.path.inspect}`
File.exists?(binary_file).should be_true

out_io, err_io = IO::Memory.new, IO::Memory.new
status = Process.run(binary_file, output: out_io, error: err_io)

{status, out_io.to_s, err_io.to_s}
yield binary_file
ensure
File.delete(code_file) if code_file
File.delete(binary_file) if binary_file
end

def build_and_run(code)
build(code) do |binary_file|
out_io, err_io = IO::Memory.new, IO::Memory.new
status = Process.run(binary_file, output: out_io, error: err_io)

{status, out_io.to_s, err_io.to_s}
end
end

def test_c(c_code, crystal_code)
c_filename = "#{__DIR__}/temp_abi.c"
o_filename = "#{__DIR__}/temp_abi.o"
Expand Down
11 changes: 11 additions & 0 deletions spec/std/io/file_descriptor_spec.cr
@@ -0,0 +1,11 @@
require "../../spec_helper"

describe IO::FileDescriptor do
it "reopen STDIN with the right mode" do
code = %q(puts "#{STDIN.blocking} #{STDIN.info.type}")
build(code) do |binpath|
`#{binpath} < #{binpath}`.chomp.should eq("true File")
`echo "" | #{binpath}`.chomp.should eq("false Pipe")
end
end
end
16 changes: 13 additions & 3 deletions src/io/file_descriptor.cr
Expand Up @@ -9,9 +9,19 @@ class IO::FileDescriptor < IO
# platform-specific.
getter fd

def initialize(@fd, blocking = false)
def initialize(@fd, blocking = nil)
@closed = system_closed?

if blocking.nil?
blocking =
case system_info.type
when .pipe?, .socket?, .character_device?
false
else
true
end
end

unless blocking || {{flag?(:win32)}}
self.blocking = false
end
Expand All @@ -25,10 +35,10 @@ class IO::FileDescriptor < IO
# Figure out the terminal TTY name. If ttyname fails we have a non-tty, or something strange.
path = uninitialized UInt8[256]
ret = LibC.ttyname_r(fd, path, 256)
return new(fd, blocking: true) unless ret == 0
return new(fd) unless ret == 0

clone_fd = LibC.open(path, LibC::O_RDWR)
return new(fd, blocking: true) if clone_fd == -1
return new(fd) if clone_fd == -1

# We don't buffer output for TTY devices to see their output right away
io = new(clone_fd)
Expand Down

0 comments on commit 9c30c26

Please sign in to comment.