I have a bit of a problem and I'm wondering if there is a better solution.  
I have a Perl program (of course) which reads STDIN and breaks it into
separate files based on a "report separator". I can construct an
appropriate file name based on information in the "trailing" separator.  
I.e. I don't know the name of the report until the report is complete.  
What I am doing at present is using the routine 'tempfile' in the
File::Temp package to create a unique file in the output directory.  Once
I get the report name from the "trailer" separator, I want to rename this
file to the correct name. However, it is possible that there will be
multiple, different reports coming in which have the same name. So, what I
want to do is put a "sequence number" as the last node in the file name.  
This means that I must generate a test file name, then see if that file
already exists. If it does, increment the sequence number, generate a new
test file name and loop. Oh, did I mention that it is possible for this
program to have several copies all running at the same time, possibly
producing different reports with identical names? So I must worry about
"race" conditions. My code, so far, looks like:

# $fn contains the file name generated by 'tempname'
# $report contains the report name
my ($number,$test);
for ($number=1;;$number++) {
        $test = "$report.$number";
        last if sysopen JUNK, $test, O_WRONLY|O_EXCL|O_CREAT;
}
close JUNK;
mv($fn,$test);

Using sysopen with those parameters, especially O_EXCL, is the only way
that I can think to ensure that the name in $test does not exist and is
created "atomically" so that no other incarnation of this program which
happens to be running at the same time will exit the for loop with the
same value in $test.  I then close this file (now a 0 length file). I then
use the "mv" function from File::Copy to rename my real data file to the
new name, replacing the 0 length file.

This is running on Linux. I don't know if the sysopen can guarantee the
"atomicity" of sysopen on other platforms.

All comments gratefully received.

--
Maranatha!
John McKown


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to