Skip to content

Commit 748b961

Browse files
authored
Merge pull request #42 from ekohl/really-fix-file-closing
Avoid closing directory we're iterating
2 parents 13dd914 + 3f344ab commit 748b961

File tree

2 files changed

+16
-12
lines changed

2 files changed

+16
-12
lines changed

lib/puppet/util.rb

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -478,13 +478,15 @@ def safe_posix_fork(stdin = $stdin, stdout = $stdout, stderr = $stderr, &block)
478478
$stderr = STDERR
479479

480480
begin
481-
Dir.foreach('/proc/self/fd') do |f|
482-
if %{^\d+$}.match?(f) && f.to_i >= 3
483-
begin
484-
IO.new(f.to_i).close
485-
rescue
486-
nil
487-
end
481+
d = Dir.new('/proc/self/fd')
482+
ignore_fds = ['.', '..', d.fileno.to_s]
483+
d.each_child do |f|
484+
next if ignore_fds.include?(f) || f.to_i < 3
485+
486+
begin
487+
IO.new(f.to_i).close
488+
rescue
489+
nil
488490
end
489491
end
490492
rescue Errno::ENOENT, Errno::ENOTDIR # /proc/self/fd not found, /proc/self not a dir

spec/unit/util_spec.rb

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -616,18 +616,20 @@ def withenv_utf8(&block)
616616
fds.each do |fd|
617617
if fd == '.' || fd == '..'
618618
next
619-
elsif ['0', '1', '2'].include? fd
619+
elsif ['0', '1', '2', '5'].include? fd
620620
expect(IO).not_to receive(:new).with(fd.to_i)
621621
else
622622
expect(IO).to receive(:new).with(fd.to_i).and_return(double('io', close: nil))
623623
end
624624
end
625625

626-
dir_expectation = receive(:foreach).with('/proc/self/fd')
626+
dir = double(Dir, fileno: '5')
627+
dir_expectation = receive(:each_child)
627628
fds.each do |fd|
628629
dir_expectation = dir_expectation.and_yield(fd)
629630
end
630-
allow(Dir).to dir_expectation
631+
allow(dir).to dir_expectation
632+
allow(Dir).to receive(:new).with('/proc/self/fd').and_return(dir)
631633
Puppet::Util.safe_posix_fork
632634
end
633635

@@ -636,7 +638,7 @@ def withenv_utf8(&block)
636638
# letting it actually close fds, which seems risky
637639
(0..2).each {|n| expect(IO).not_to receive(:new).with(n)}
638640
(3..256).each {|n| expect(IO).to receive(:new).with(n).and_return(double('io', close: nil)) }
639-
allow(Dir).to receive(:foreach).with('/proc/self/fd').and_raise(Errno::ENOENT)
641+
allow(Dir).to receive(:new).with('/proc/self/fd').and_raise(Errno::ENOENT)
640642

641643
Puppet::Util.safe_posix_fork
642644
end
@@ -646,7 +648,7 @@ def withenv_utf8(&block)
646648
# letting it actually close fds, which seems risky
647649
(0..2).each {|n| expect(IO).not_to receive(:new).with(n)}
648650
(3..256).each {|n| expect(IO).to receive(:new).with(n).and_return(double('io', close: nil)) }
649-
allow(Dir).to receive(:foreach).with('/proc/self/fd').and_raise(Errno::ENOTDIR)
651+
allow(Dir).to receive(:new).with('/proc/self/fd').and_raise(Errno::ENOTDIR)
650652

651653
Puppet::Util.safe_posix_fork
652654
end

0 commit comments

Comments
 (0)