Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > can you flock a file or lock a file before opening it.

Reply
Thread Tools

can you flock a file or lock a file before opening it.

 
 
John Smith
Guest
Posts: n/a
 
      12-01-2003
I want to ensure that only one person at a time can edit a file using my
perl script.

From what I've read, it appears that you can only flock a file after opening
it.
So I guess it would look like this:

- open the file for writing
- flock the file for exclusive (2)
- update the file
- unflock the file or flock (
- close the file

I'm suspecting that if the file is already open when you try to flock it,
the flock function will return an error code?


Now this would work great if you are trying to append to a file, as in a log
file, but what if you want to change info in the file? Maybe I'm not doing
this properly.

- My program opens (for read), reads the entire file, and closes the file.
- Then it open (for write), re-writes the complete file (with the updates),
and closes the file.


From what I understand, if I can't lock the file before opening it, then
this flock won't help me.


Now it turns out that my perl script will be the only program accessing
these files.
So I thought, that maybe I could have a dummy file that I would flock. If I
can flock this file, then I would allow my perl program to read, delete,
re-write or whatever to my other data files. Once I'm done, I unflock the
dummy file.


Another question... My perl script runs on a web server and when it is
called, it does a few quick things and terminates. When the perl script
terminates, will all files locked by the perl script be unlocked upon
termination (in the event that an error occured and it ended prematurely -
not that it would).


I think I was told that the web server is running perl 5.8???
This brings me to a final question.
Is there a function that can retrieve the version of Perl that is running?
This would be nice since the server is like 3 hours away (200 miles away!)


Thanks for all.
G.Doucet


 
Reply With Quote
 
 
 
 
William Herrera
Guest
Posts: n/a
 
      12-01-2003
On Mon, 01 Dec 2003 04:28:47 GMT, "John Smith" <(E-Mail Removed)> wrote:

>I want to ensure that only one person at a time can edit a file using my
>perl script.
>
>From what I've read, it appears that you can only flock a file after opening
>it.
>So I guess it would look like this:
>
> - open the file for writing
> - flock the file for exclusive (2)
> - update the file
> - unflock the file or flock (
> - close the file
>
>I'm suspecting that if the file is already open when you try to flock it,
>the flock function will return an error code?


If the file is already locked, the program will either wait for the lock to be
released or will return an error. This depends on the second argument to flock.
See the docs in perlfunc:
===
OPERATION is one of LOCK_SH, LOCK_EX, or LOCK_UN, possibly combined with
LOCK_NB. These constants are traditionally valued 1, 2, 8 and 4, but you can
use the symbolic names if you import them from the Fcntl module, either
individually, or as a group using the ':flock' tag. LOCK_SH requests a shared
lock, LOCK_EX requests an exclusive lock, and LOCK_UN releases a previously
requested lock. If LOCK_NB is bitwise-or'ed with LOCK_SH or LOCK_EX then flock
will return immediately rather than blocking waiting for the lock (check the
return status to see if you got it).
===

>So I thought, that maybe I could have a dummy file that I would flock. If I
>can flock this file, then I would allow my perl program to read, delete,
>re-write or whatever to my other data files. Once I'm done, I unflock the
>dummy file.


I use this in one script that writes its log entries to a db file (don't ask
why ). Here's a code excerpt:

dblogflock();
tie(%lastogin, 'DB_File', $login_db) or mydie('Cannot tie login DB',
__LINE__);
$lastlogin{$user} = time;
untie %logins;
undblogflock();

sub dblogflock {
open(LDBM, ">$loglockfile") or mydie("loglockfile error: $!", __LINE__);
flock LDBM, 2;
}

sub undblogflock {
close LDBM;
}

Note that this will wait until the other process releases the lock before it
completes.

---
Use the domain skylightview (dot) com for the reply address instead.
 
Reply With Quote
 
 
 
 
Brian McCauley
Guest
Posts: n/a
 
      12-01-2003
"John Smith" <(E-Mail Removed)> writes:

[ Unless you have permission from Microsoft to use their domain in
your mail address then doing so is rude to say the least (and probably
actionable). ]

> I want to ensure that only one person at a time can edit a file using my
> perl script.
>
> From what I've read, it appears that you can only flock a file after opening
> it.
> So I guess it would look like this:
>
> - open the file for writing
> - flock the file for exclusive (2)
> - update the file
> - unflock the file or flock (
> - close the file
>
> I'm suspecting that if the file is already open when you try to flock it,
> the flock function will return an error code?


Just being open will not interact with locking unless you have
mandatory locking configured on the file at the OS level.

flock() will block rather than return a failure code unless to
explicitly ask for non-blocking mode.

> - My program opens (for read), reads the entire file, and closes the file.
> - Then it open (for write), re-writes the complete file (with the updates),
> and closes the file.
>
> From what I understand, if I can't lock the file before opening it, then
> this flock won't help me.


So open the file read/write in the first place then you don't need to
close it and can hold the lock throughout.

> So I thought, that maybe I could have a dummy file that I would flock. If I
> can flock this file, then I would allow my perl program to read, delete,
> re-write or whatever to my other data files. Once I'm done, I unflock the
> dummy file.


That too, is a valid approach.

Be aware that to cope gracefully with abnormal termination one usually
would write the updated file to a new file then rename that file over
the old one. This trick would need to combined with the
aforementioned "separate lockfile" approach on OSs that lack an atomic
rename-over-existing-file.

To save re-inventing the wheel, see the module IO::AtomicFile on CPAN.

> Another question...


Errr....

> My perl script runs on a web server and when it is called, it does a
> few quick things and terminates. When the perl script terminates,
> will all files locked by the perl script be unlocked upon
> termination (in the event that an error occured and it ended
> prematurely - not that it would).


[ Er, what was your question? I shall assume "It is true that ...?"]

Under CGI yes, the above is true, because a CGI script runs as a
separate process. When the process terminates all resources held by
it are (or at least should be) freed by the OS.

This is not necessarily the case under other mechanisms that may be
used to connect your Perl script to the web server (mod_perl, FastCGI,
whatever).

Using a bare filehandle you can avoid this thus:

local *FOO;
open FOO, '<+', $filename or die "Can't open $filename: $!";

This will close the file on exiting the current lexical scope, whether
normally or abnormally.

However, I suggest that people should always open files using
filehandle references rather than bare filehandles except when
backward compatability with old versions of Perl is needed. (And if
you are using IO::AtomicFile you'd be using a reference anyhow).

open my $foo, '<+', $filename or die "Can't open $filename: $!";

This will close the file upon destruction of the last copy of the
reference held in $foo. This will close the file upon termination so
long as your program hasn't leaked any copies of the reference in
$foo.

Note that under mod_perl's Registry you can't declare $foo as a
lexical variable at the file-scope an then use $foo within a
subroutine.

A workround for the latter is to use a package variable and local().

open local our $foo, '<+', $filename or die "Can't open $filename: $!";

> I think I was told that the web server is running perl 5.8???
> This brings me to a final question.
> Is there a function that can retrieve the version of Perl that is running?
> This would be nice since the server is like 3 hours away (200 miles away!)


$]

--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How do you use flock and clean up lock files? John Carter Ruby 16 08-15-2006 04:03 AM
How do you lock a file BEFORE changes are made? J. Romano Perl Misc 6 09-04-2004 12:47 AM
Threading - Why Not Lock Objects Rather than lock the interpreter Fuzzyman Python 3 12-05-2003 10:43 PM
I can't flock, it returns 0, any ideas. Guy Perl Misc 10 12-01-2003 06:24 PM
Confused about locking a file via file.flock(File::LOCK_EX) Ludwigi Beethoven Ruby 5 07-26-2003 03:26 PM



Advertisments