summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/contrib/qtool.pl
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/contrib/qtool.pl')
-rwxr-xr-xcontrib/sendmail/contrib/qtool.pl47
1 files changed, 45 insertions, 2 deletions
diff --git a/contrib/sendmail/contrib/qtool.pl b/contrib/sendmail/contrib/qtool.pl
index ba944c2..d6a63ec 100755
--- a/contrib/sendmail/contrib/qtool.pl
+++ b/contrib/sendmail/contrib/qtool.pl
@@ -3,7 +3,7 @@
## Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers.
## All rights reserved.
##
-## $Id: qtool.pl,v 8.28 2002/06/27 23:06:16 gshapiro Exp $
+## $Id: qtool.pl,v 8.29 2007/02/16 01:12:08 ca Exp $
##
use strict;
use File::Basename;
@@ -69,6 +69,12 @@ my $new_condition;
my $qprefix;
my $queuegroups = 0;
my $conditions = new Compound();
+my $fcntl_struct = 's H60';
+my $fcntl_structlockp = pack($fcntl_struct, Fcntl::F_WRLCK,
+ "000000000000000000000000000000000000000000000000000000000000");
+my $fcntl_structunlockp = pack($fcntl_struct, Fcntl::F_UNLCK,
+ "000000000000000000000000000000000000000000000000000000000000");
+my $lock_both = -1;
Getopt::Std::getopts('bC:de:Qs:', \%opts);
@@ -340,7 +346,9 @@ sub add_source
## Opens a file for read/write and uses flock to obtain a lock on the
## file. The flock is Perl's flock which defaults to flock on systems
## that support it. On systems without flock it falls back to fcntl
-## locking.
+## locking. This script will also call fcntl explicitly if flock
+## uses BSD semantics (i.e. if both flock() and fcntl() can successfully
+## lock the file at the same time)
##
## Parameters:
## file_name -- The name of the file to open and lock.
@@ -358,6 +366,24 @@ sub lock_file
my $file_name = shift;
my $result;
+ if ($lock_both == -1)
+ {
+ if (open(DEVNULL, '>/dev/null'))
+ {
+ my $flock_status = flock(DEVNULL, Fcntl::LOCK_EX | Fcntl::LOCK_NB);
+ my $fcntl_status = fcntl (DEVNULL, Fcntl::F_SETLK, $fcntl_structlockp);
+ close(DEVNULL);
+
+ $lock_both = ($flock_status && $fcntl_status);
+ }
+ else
+ {
+ # Couldn't open /dev/null. Windows system?
+ $lock_both = 0;
+ }
+ }
+
+
$result = sysopen(FILE_TO_LOCK, $file_name, Fcntl::O_RDWR);
if (!$result)
{
@@ -370,6 +396,15 @@ sub lock_file
return (undef, "Could not obtain lock on '$file_name': $!");
}
+ if ($lock_both)
+ {
+ my $result2 = fcntl (FILE_TO_LOCK, Fcntl::F_SETLK, $fcntl_structlockp);
+ if (!$result2)
+ {
+ return (undef, "Could not obtain fcntl lock on '$file_name': $!");
+ }
+ }
+
return (\*FILE_TO_LOCK, undef);
}
@@ -396,6 +431,14 @@ sub unlock_file
{
return "Unlock failed on '$result': $!";
}
+ if ($lock_both)
+ {
+ my $result2 = fcntl ($file, Fcntl::F_SETLK, $fcntl_structunlockp);
+ if (!$result2)
+ {
+ return (undef, "Fcntl unlock failed on '$result': $!");
+ }
+ }
return undef;
}
OpenPOWER on IntegriCloud