Ras has asked for the wisdom of the Perl Monks concerning the following question:

Does anybody know how to lock a specific area in a file? thanks in advance

Replies are listed 'Best First'.
Re: Locking an area in a file
by Dominus (Parson) on May 04, 2001 at 00:29 UTC
    Says Ras:
    Does anybody know how to lock a specific area in a file?
    You need to use the fcntl() function and pass a struct flock structure as the third argument; you can construct this struct using Perl's pack function. Here's an example program:
    #!/usr/bin/perl # System V record locking demonstration # Author: Mark Jason Dominus 20010503 # This program is in the public domain use Fcntl qw(F_GETLK F_SETLK F_WRLCK F_RDLCK F_UNLCK ); my %type = map {&$_ => $_} qw(F_WRLCK F_RDLCK F_UNLCK); my @whence = ('from beginning', 'from current position', 'from end'); # this is correct for my I386 linux box, but will be different # depending on your OS and hardwre $struct_flock = "s s l l L"; $file = $0; open F, "+< $file" or die "Couldn't open file $file: $!; aborting"; do_lock(0, 10, F_WRLCK); if (fork()) { # parent wait; } else { do_lock(9, 20, F_WRLCK); } exit; # see make_lock for an explanation of the arguments sub do_lock { my $lock_s = make_lock(@_); if (fcntl(F, F_SETLK, $lock_s)) { print "Got lock.\n"; } else { print "Lock failed: $!\n\t", lock_struct_to_string($lock_s), "\n"; } } sub lock_struct_to_string { my $s = shift; my @d = unpack $struct_flock, $s; my $type = $type{$d[0]} || '(unknown)'; my $whence = $whence[$d[1]]; my ($start, $len, $pid) = @d[2,3,4]; my $end = $start + $len - 1; "$start-$end [type: $type; whence: $whence; pid: $pid]"; } # arguments: lock $length bytes of the file, starting at position $pos +ition # $type should be F_WRLCK for a write lock, F_RDLCK for a read lock # F_UNLCK releases the lock sub make_lock { my ($position, $length, $type) = @_; $type = F_WRLCK unless defined $type; return pack $struct_flock, $type, 0, $position, $length, $$; }
    This locks bytes 0-9 of a file and prints a success message. Then it forks a child process; the parent waits while the child tries to lock bytes 9-28. The child fails to get the lock (because byte 9 is locked by the parent) and prints a diagnostic message. If you change the code so that the child tries to lock a non-overlapping region of the file, then the lock succeeds.

    Note that this is the only time I have ever used the fcntl-style region locking, so I have probably not used the best practice here, whatever it is. All I can vouch for is that the example does seem to work.

    Hope this helps.

    --
    Mark Dominus
    Perl Paraphernalia

(Ovid) Re: Locking an area in a file
by Ovid (Cardinal) on May 04, 2001 at 00:03 UTC
    Perl doesn't support this directly. The code is too long to post here, but check page 267 of the Perl Cookbook for the program lockarea.

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.