locking
authorheiko
Thu, 25 Jan 2007 14:21:16 +0000
changeset 44 70d21f5411cc
parent 43 c6b65799fdb3
child 45 55a16b2e10bc
locking
exim-exigrey.pl
--- a/exim-exigrey.pl	Tue Jan 16 12:38:17 2007 +0000
+++ b/exim-exigrey.pl	Thu Jan 25 14:21:16 2007 +0000
@@ -5,6 +5,7 @@
 use strict;
 use warnings;
 use Carp;
+use Fcntl qw(:flock);
 
 # You may choose, but DB_File's footprint is smaller.
 # perl -MDB_File -e 'tie %h, ...':	real    0m0.063s
@@ -25,6 +26,7 @@
 sub getDBDir();
 sub findExim(;$);
 sub connectDB($$);
+sub disconnectDB();
 sub getDefault() { %DEFAULT };
 
 # Usage:
@@ -66,6 +68,7 @@
 		}
 	}
 	untie %h;
+	disconnectDB();
 	return $rc;
 }
 
@@ -108,13 +111,15 @@
 	die "Can't find exim binary (missing .../sbin dirs in PATH?";
 }
 
+{
+	my $fh;
 sub connectDB($$) {
     my ($h, $db) = @_;
     $db = getDBDir() ."/$db" unless $db =~ m(^\.?/);
 
     # Creation of DB-File if it doesn't exist
     # to avoid races we change our own uid/gid for creation of
-    # this file
+    # this file.
     if (!-f $db) {
 	(my $dir = $db) =~ s/^(.*)\/.*?$/$1/;
 
@@ -128,6 +133,11 @@
 	umask $umask;
     }
 
+    # We try to open and lock the database file to avoid
+    # a race.
+    open($fh, $db) or die "Can't open $db: $!";
+    flock($fh, LOCK_EX) or die "Can't lock $db: $!";
+
     # now test which of the DB-Modules has been loaded
 
     if (exists &BerkeleyDB::Hash::TIEHASH) {
@@ -147,6 +157,10 @@
 
     die "Can't connect to database driver";
 }
+
+sub disconnectDB() {
+    close($fh);
+} }
 1;
 
 # vim:aw: