[ruby-core:117733] [Ruby master Bug#20461] Unreadable pipe included in the readable IO of IO.select

Issue #20461 has been reported by yamam (Masanari Yamamoto). ---------------------------------------- Bug #20461: Unreadable pipe included in the readable IO of IO.select https://bugs.ruby-lang.org/issues/20461 * Author: yamam (Masanari Yamamoto) * Status: Open * ruby -v: ruby 3.4.0dev (2024-04-27T12:55:28Z master c844968b72) [x86_64-linux] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- When executing the following script, pipe_r is not supposed to be readable because no writing is done to pipe_w, but pipe_r is included in the return value rs of IO.select. Since it is not possible to read from pipe_r, the IO::EAGAINWaitReadable exception is raised. ```ruby pipe_r, pipe_w = IO.pipe 1000.times do |i| File.popen(['seq', '1', '1000']) do |popen_r| j = 0 while true rs, ws, = IO.select([popen_r, pipe_r]) if rs.include?(popen_r) unless popen_r.gets break end end if rs.include?(pipe_r) puts "IO.select BUG pipe_r is not readable! i = #{i} j = #{j}" p pipe_r.read_nonblock(1) end j += 1 end end end ``` ``` $ ruby select.rb IO.select BUG pipe_r is not readable! i = 0 j = 20 <internal:io>:63:in `read_nonblock': Resource temporarily unavailable - read would block (IO::EAGAINWaitReadable) from select.rb:14:in `block (2 levels) in <main>' from select.rb:3:in `popen' from select.rb:3:in `block in <main>' from select.rb:2:in `times' from select.rb:2:in `<main>' [1] 73732 exit 1 ruby select.rb ``` -- https://bugs.ruby-lang.org/

Issue #20461 has been updated by yamam (Masanari Yamamoto). Using git bisect, I found that the following commit is the cause of the bug: https://github.com/ruby/ruby/commit/49a55f28abdcf3dea1f84ec5b59cfbedc37f44bf ---------------------------------------- Bug #20461: Unreadable pipe included in the readable IO of IO.select https://bugs.ruby-lang.org/issues/20461#change-108146 * Author: yamam (Masanari Yamamoto) * Status: Open * ruby -v: ruby 3.4.0dev (2024-04-27T12:55:28Z master c844968b72) [x86_64-linux] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- When executing the following script, pipe_r is not supposed to be readable because no writing is done to pipe_w, but pipe_r is included in the return value rs of IO.select. Since it is not possible to read from pipe_r, the IO::EAGAINWaitReadable exception is raised. ```ruby pipe_r, pipe_w = IO.pipe 1000.times do |i| IO.popen(['seq', '1', '1000']) do |popen_r| j = 0 while true rs, ws, = IO.select([popen_r, pipe_r]) if rs.include?(popen_r) unless popen_r.gets break end end if rs.include?(pipe_r) puts "IO.select BUG pipe_r is not readable! i = #{i} j = #{j}" p pipe_r.read_nonblock(1) end j += 1 end end end ``` ``` $ ruby select.rb IO.select BUG pipe_r is not readable! i = 0 j = 20 <internal:io>:63:in `read_nonblock': Resource temporarily unavailable - read would block (IO::EAGAINWaitReadable) from select.rb:14:in `block (2 levels) in <main>' from select.rb:3:in `popen' from select.rb:3:in `block in <main>' from select.rb:2:in `times' from select.rb:2:in `<main>' [1] 73732 exit 1 ruby select.rb ``` -- https://bugs.ruby-lang.org/
participants (1)
-
yamam (Masanari Yamamoto)