Tempfile.unlink $B8e$K(B tempfile.close

e$B$5$H$&$U$_$d$9e(B @ OSS e$B%F%/%N%m%8$G$9!#e(B

Tempfile e$B%*%V%8%’%/%H$re(B unlink e$B$7$?8e$Ke(B close e$B$9$k$H!"e(B
e$B0J2<$N$h$&$KNc30$,H/@8$7$F$7$^$$$^$9!#e(B

$ ruby -v
ruby 1.8.6 (2008-03-03 patchlevel 114) [x86_64-linux]
e$B$A$J$_$Ke(B Ruby 1.9.0-1 e$B$G$OH/@8$7$^$;$s$G$7$?!#e(B

$ cat ~/test.rb
require ‘tempfile’
temp = Tempfile.new(‘test’)
temp.unlink
temp.close

$ ruby test.rb
/usr/lib/ruby/1.8/tempfile.rb:84:in _close': undefined method[]=’ for
nil:NilClass (NoMethodError)
from /usr/lib/ruby/1.8/tempfile.rb:97:in `close’
from /home/fumiyas/test.rb:5

e$B<B:]$KLdBj$H$J$C$?$N$O!"0J2<$N$h$&$J%3!<%I$G$9e(B:

input_tmp = Tempfile.new('chimera-filter')
input_tmp.unlink
super(input, input_tmp)
input_tmp.rewind

stdout_reader, stdout_writer = IO.pipe
stderr_reader, stderr_writer = IO.pipe
pid = Process.fork do
  begin
    $stdin.reopen(input_tmp)
    input_tmp.close               e$B"+e(B e$B$3$3$GMn$A$ke(B
    $stdout.reopen(stdout_writer)
    stdout_writer.close
    stdout_reader.close
    $stderr.reopen(stderr_writer)
    stderr_writer.close
    stderr_reader.close
    ENV['PATH'] = @path if (@path)
    Kernel.exec([@command, @arg0], *@args)
  rescue Exception => e
    $stderr.puts("#{$0}: ERROR: #{__FILE__}: exec failed: 

#{@command}: #{e}")
exit!(1)
end
end

さとうふみやす @ OSS テクノロジです。

At Thu, 20 Mar 2008 15:47:56 +0900,
SATOH Fumiyasu wrote:

Tempfile オブジェクトを unlink した後に close すると、
以下のように例外が発生してしまいます。

反応なしですが、BTS に登録したほうがいいのでしょうか?

あまり美しくない感じですが、とりあえずパッチを
作ってみました(添付)。Ruby 1.8.7-preview1 で作成
しましたが、たぶん Ruby 1.8.6 系統にもあたります。

unlink 後の open でも同様の問題があるのですが、
修正するなら以下のような感じ?

— lib/tempfile.rb 2008-04-16 11:08:19.000000000 +0900
+++ lib/tempfile.rb 2008-04-16 11:19:25.000000000 +0900
@@ -131,6 +131,9 @@
@@cleanlist.delete(@tmpname)
@data = @tmpname = nil
ObjectSpace.undefine_finalizer(self)

  •  def self.open
    
  • raise “cannot open unlinked tempfile”
  •  end
    
    rescue Errno::EACCES
    # may not be able to unlink on Windows; just ignore
    end

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:34094] tempfile.unlink e$B8e$Ke(B
tempfile.close”
on Thu, 20 Mar 2008 15:47:56 +0900, SATOH Fumiyasu
[email protected] writes:

|Tempfile e$B%*%V%8%'%/%H$re(B unlink e$B$7$?8e$Ke(B close e$B$9$k$H!"e(B
|e$B0J2<$N$h$&$KNc30$,H/@8$7$F$7$^$$$^$9!#e(B
|
|$ ruby -v
|ruby 1.8.6 (2008-03-03 patchlevel 114) [x86_64-linux]
|e$B$A$J$_$Ke(B Ruby 1.9.0-1 e$B$G$OH/@8$7$^$;$s$G$7$?!#e(B

1.9e$B$G$OBP1~$5$l$F$^$9$M!#0J2<$N$h$&$J%Q%C%A$,8z$/$_$?$$$G$9!#e(B
1.8.7e$B$KF~$l$k$+$I$&$+$O$*G$$;$7$^$9e(B > knue$B$5$s!#e(B

diff --git a/ChangeLog b/ChangeLog
index 9994dae…797d766 100644
— a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Wed Apr 16 14:22:42 2008 Yukihiro M. [email protected]
+

    • lib/tempfile.rb (Tempfile::_close): check @data before modifying
  • it backported from 1.9. [ruby-dev:34094]
    • lib/tempfile.rb (Tempfile::close): clear @data and @tmpname.

Wed Apr 16 06:03:45 2008 Akinori MUSHA [email protected]

  • test/ruby/test_settracefunc.rb (TestSetTraceFunc#test_event):
    diff --git a/lib/tempfile.rb b/lib/tempfile.rb
    index c728dbc…703e781 100644
    — a/lib/tempfile.rb
    +++ b/lib/tempfile.rb
    @@ -95,7 +95,8 @@ class Tempfile < DelegateClass(File)

def _close # :nodoc:
@tmpfile.close if @tmpfile

  • @data[1] = @tmpfile = nil
  • @tmpfile = nil
  • @data[1] = nil if @data
    end
    protected :_close

@@ -117,6 +118,7 @@ class Tempfile < DelegateClass(File)
_close
@clean_proc.call
ObjectSpace.undefine_finalizer(self)

  • @data = @tmpname = nil
    end

Unlinks the file. On UNIX-like systems, it is often a good idea