1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Switch conflicting chdir warning to RuntimeError

The documentation already stated this was an error in one case
(when it was previously a warning).  Describe the other case,
where chdir without block is called inside block passed to chdir.

Fixes [Bug #15661]
This commit is contained in:
Jeremy Evans 2020-09-25 13:29:20 -07:00
parent 0164ac70a1
commit 5d7953f86b
Notes: git 2020-09-29 00:34:32 +09:00
2 changed files with 31 additions and 4 deletions

5
dir.c
View file

@ -1024,7 +1024,8 @@ chdir_restore(VALUE v)
* block. <code>chdir</code> blocks can be nested, but in a
* multi-threaded program an error will be raised if a thread attempts
* to open a <code>chdir</code> block while another thread has one
* open.
* open or a call to <code>chdir</code> without a block occurs inside
* a block passed to <code>chdir</code> (even in the same thread).
*
* Dir.chdir("/var/spool/mail")
* puts Dir.pwd
@ -1064,7 +1065,7 @@ dir_s_chdir(int argc, VALUE *argv, VALUE obj)
if (chdir_blocking > 0) {
if (!rb_block_given_p() || rb_thread_current() != chdir_thread)
rb_warn("conflicting chdir during another chdir block");
rb_raise(rb_eRuntimeError, "conflicting chdir during another chdir block");
}
if (rb_block_given_p()) {

View file

@ -99,8 +99,12 @@ class TestDir < Test::Unit::TestCase
ENV["HOME"] = @pwd
Dir.chdir do
assert_equal(@pwd, Dir.pwd)
Dir.chdir(@root)
assert_equal(@root, Dir.pwd)
assert_raise(RuntimeError) { Dir.chdir(@root) }
assert_equal(@pwd, Dir.pwd)
Dir.chdir(@root) do
assert_equal(@root, Dir.pwd)
end
assert_equal(@pwd, Dir.pwd)
end
ensure
@ -121,6 +125,28 @@ class TestDir < Test::Unit::TestCase
end
end
def test_chdir_conflict
@pwd = Dir.pwd
q = Queue.new
t = Thread.new do
q.pop
Dir.chdir(@pwd) rescue $!
end
Dir.chdir(@pwd) do
q.push nil
assert_instance_of(RuntimeError, t.value)
end
t = Thread.new do
q.pop
Dir.chdir(@pwd){} rescue $!
end
Dir.chdir(@pwd) do
q.push nil
assert_instance_of(RuntimeError, t.value)
end
end
def test_chroot_nodir
skip if RUBY_PLATFORM =~ /android/
assert_raise(NotImplementedError, Errno::ENOENT, Errno::EPERM