[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

Re: [FWP] Puzzle - Temp file creation (HINTs)



[OK, let's try the right list address this time]

Vicki Brown wrote:
> sub call {
> 
>    my $db = shift;
> 
>    # find a suitable temporary name
>    $target = "quickblast${$}aaaa";
>    my $tries = 100;
>    while (--$tries) {
>      last if IO::File->new($target,O_WRONLY|O_EXCL|O_CREAT,0600);
>      $target++;
>    }
>    return unless $tries;
> 
>    unlink $target;
>    symlink($db,$target) || die "Couldn't symlink $db=>$target";
> 
>    ...
>   return $target;
> }
> 
> What's wrong with this code?

Apart from $target being incremented wrongly (see previous thread), there's a
race condition here between unlink and symlink. I'm no expert, but I'd do this
(untested):

sub call{
  my $db=shift;
  my $target="quickblast$$.";
  my $tries=100;
  while(--$tries){
    last if IO::File->new($target.$tries,O_WRONLY|O_EXCL|O_CREAT,0600);
  }
  return unless $tries;
  $target.=$tries;

  # Tricky bit. We need another unique name for the symlink
  $tries=100;
  while(--$tries){
    last if symlink($db,"$target.$tries");
    return if $!!=EEXIST;
  }
  return unless $tries;

  # This is atomic, so no race condition
  rename "$target.tries",$target;

  return $target;
}

On the other hand, why don't you just use $db as it is?
Also, there are two behaviours on failure. If the temp file can't be created,
you return, but if you can't symlink, you die. I haven't addressed that in my
sub, but it should be made more consistent.

-- 
	Peter Haworth	pmh@edison.ioppublishing.com
"Things are more like they are now than they ever were before."      
		-- Dwight D. Eisenhower


==== Want to unsubscribe from Fun With Perl?  Well, if you insist...
==== Send email to <fwp-request@technofile.org> with message _body_
====   unsubscribe