From: Tanaka Akira Date: 2002-09-27T00:57:21+09:00 Subject: [ruby-dev:18392] Re: pstore.rb can make a broken store In article <20020926134339.C8DAE1EE12@milestones.dm4lab.to>, YANAGAWA Kazuhisa writes: > $BJL$N%U%!%$%k$K=q$$$F(B rename $B$9$k$H$+!$2?$+$b$C$H0BA4$J $B$H;W$&$N$G$9$,!$$I$&$G$7$g$&$+!%(B > > # $B$@$$$?$$8e$KIU$1$?%Q%C%A$N$h$&$J46$8$G$$$$$N$+$J(B? $B$D$$$G$K(B abort $B$7(B > # $B$?$H$-(B content $B$r(B unref $B$7$F$J$$$N$bD>$7$F$^$9!%(B lock $B$7$D$D(B rename $B$H$$$&OC$O$7$P$i$/A0$K9M$($?$3$H$,$"$k$s$G$9$,!"$b(B $B$&$9$3$7J#;($K$J$k$H;W$$$^$9!#(B $B$"$k%U%!%$%k$r(B open $B$7$F(B LOCK_EX $B$J(B flock $B$K@.8y$7$?>l9g$G$b!"$=$l$,B((B $B:B$K%m%C%/$r3MF@$7$?$3$H$K$O$J$j$^$;$s!#$3$l$OB>$N%W%m%;%9$,$=$N%U%!%$(B $B%k$r(B rename $B$K$h$C$F$9$jBX$($F$+$i=*N;$7$?7k2L$H$7$F%m%C%/$,2rJ|$5$l$?(B $B$+$i$+$b$7$l$J$$$+$i$G$9!#$3$N>l9g!"$=$N%U%!%$%kL>$N:G?7$N%U%!%$%k$KBP(B $B$9$k%m%C%/$,3MF@$G$-$?$o$1$G$O$J$/!"(Bunlink $B$5$l$F$7$^$C$?0UL#$N$J$$%U%!(B $B%$%k$KBP$9$k%m%C%/$,3MF@$G$-$?$@$1$J$N$G!"$d$jD>$5$J$$$H$$$1$^$;$s!#(B $B$7$P$i$/A0$K$9$h$&$J=hCV$,I,MW$G$O$J$$(B $B$G$7$g$&$+!#(B def open_write(filename) dirname = File.dirname filename basename = File.basename filename tmpname = "#{dirname}/,#{basename},#$$" 1.times { begin target = File.open(filename, File::RDWR|File::CREAT) stat1 = target.stat target.flock(File::LOCK_EX) stat2 = File.stat(filename) redo if stat1.ino != stat2.ino begin File.open(tmpname, 'w') {|tmp| yield tmp } stat2 = File.stat(filename) File.rename(tmpname, filename) if stat1.ino == stat2.ino ensure File.unlink tmpname if FileTest.exist? tmpname end ensure target.close end } end def open_read(filename, &block) File.open(filename, &block) end $B$"$H!"$D$$$G$K$$$($P(B "rb" $B$G(B open $B$7$?$b$N$K$O(B LOCK_EX $B$G$-$J$$(B OS $B$b(B $B$"$j$^$9!#(BSolaris $B$H$+!#(B $B$5$i$K$D$$$G$K$$$($P!"(Bflock $B$h$j(B fcntl $B$N$[$&$,E,@Z$J$3$H$b$"$k$h$&$G(B $B$9!#(BNFS $B$4$7$G$b8z$/>l9g$,$"$k$H$+!#(B ($B