The logic is OK but you have created a possible infinite loop. sysopen may fail with the flags you have if the file exists but it may fail for other reasons ie Permissions. If you have a perms problem you code will loop forever burning 100% CPU in all liklihood. Here is a tempfile function we use that may be the sort of thing you are after. It returns the locked $fh and $filename (for unlinking or whatever) if it succeeds and limits the number of retries to less than infinity :-) Note File::Temp is a well tested solution and offers features not present in this function.
use Fcntl; # need constants O_CREAT | O_EXCL | O_RDWR
sub get_tempfile {
my ( $dir, $prefix, $max_tries ) = @_;
$dir ||= '/tmp';
$prefix ||= 'temp';
$max_tries ||= 10;
my @CHARS = ( 'A' .. 'Z', 'a' .. 'z', 0 .. 9, '_' );
ui_system_error( "$dir is not a directory" ) unless -d $dir;
ui_system_error( "$dir is not writable" ) unless -w $dir;
$dir =~ s!/$!!;
my $fh;
for ( 0 .. $max_tries ) {
my $name = sprintf "$prefix-%d-", time();
$name .= $CHARS[ int( rand( $#CHARS ) ) ] for 1..10;
my $path = "$dir/$name";
return ($fh, $name) if sysopen($fh, $path, O_CREAT | O_EXCL | O_
+RDWR, 0600);
}
ui_system_error( "Could not create unique filename after $max_trie
+s" );
}