1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
# frozen_string_literal: true
require 'test/unit'
require 'io/wait'
# test uncommon device types to check portability problems
# We may optimize IO#wait_*able for non-Linux kernels in the future
class TestIOWaitUncommon < Test::Unit::TestCase
def test_tty_wait
check_dev('/dev/tty', mode: 'w+') do |tty|
assert_include [ nil, tty ], tty.wait_readable(0)
assert_equal tty, tty.wait_writable(1), 'portability test'
end
end
def test_fifo_wait
omit 'no mkfifo' unless File.respond_to?(:mkfifo) && IO.const_defined?(:NONBLOCK)
require 'tmpdir'
Dir.mktmpdir('rubytest-fifo') do |dir|
fifo = "#{dir}/fifo"
assert_equal 0, File.mkfifo(fifo)
rd = Thread.new { File.open(fifo, IO::RDONLY|IO::NONBLOCK) }
begin
wr = File.open(fifo, IO::WRONLY|IO::NONBLOCK)
rescue Errno::ENXIO
Thread.pass
end until wr
assert_instance_of File, rd.value
assert_instance_of File, wr
rd = rd.value
assert_nil rd.wait_readable(0)
assert_same wr, wr.wait_writable(0)
wr.syswrite 'hi'
assert_same rd, rd.wait_readable(1)
wr.close
assert_equal 'hi', rd.gets
rd.close
end
end
# used to find portability problems because some ppoll implementations
# are incomplete and do not work for certain "file" types
def check_dev(dev, m = :wait_readable, mode: m == :wait_readable ? 'r' : 'w', &block)
begin
fp = File.open(dev, mode)
rescue Errno::ENOENT
return # Ignore silently
rescue SystemCallError => e
omit "#{dev} could not be opened #{e.message} (#{e.class})"
end
if block
yield fp
else
assert_same fp, fp.__send__(m)
end
ensure
fp&.close
end
def test_wait_readable_urandom
check_dev('/dev/urandom')
end
def test_wait_readable_random
check_dev('/dev/random') do |fp|
assert_nothing_raised do
fp.wait_readable(0)
end
end
end
def test_wait_readable_zero
check_dev('/dev/zero')
end
def test_wait_writable_null
check_dev(IO::NULL, :wait_writable)
end
end
|