# from chiark-utils, except using flock. It has the benefit of
# it being possible to safely remove the lockfile when done.
# See below for a correctness proof.
- local rightfile
+ local stat
while true; do
eval "exec $_lockfd<>$_lockfile"
flock -x $_lockfd || return $?
# actually a synthetic symlink in /proc and we aren't
# guaranteed that our stat(2) won't lose the race with an
# rm(1) between reading the synthetic link and traversing the
- # file system to find the inum. Perl is very fast so use that.
- rightfile=$( perl -e '
- open STDIN, "<&'$_lockfd'" or die $!;
- my $fd_inum = (stat STDIN)[1]; die $! unless defined $fd_inum;
- my $file_inum = (stat $ARGV[0])[1];
- print "y\n" if $fd_inum eq $file_inum;
- ' "$_lockfile" )
- if [ x$rightfile = xy ]; then break; fi
+ # file system to find the inum. stat(1) translates '-' into an
+ # fstat(2) of FD 0. So we just need to arrange the FDs properly
+ # to get the fstat(2) we need. stat will output two lines like:
+ # WW.XXX
+ # YY.ZZZ
+ # which need to be separated and compared.
+ if stat=$( stat -L -c '%D.%i' - $_lockfile 0<&$_lockfd 2>/dev/null )
+ then
+ local file_stat
+ local fd_stat
+
+ # match on literal newline
+ fd_stat=${stat%
+*}
+ file_stat=${stat#*
+}
+ if [ "$fd_stat" = "$file_stat" ] ; then break; fi
+ fi
# Some versions of bash appear to be buggy if the same
# $_lockfile is opened repeatedly. Close the current fd here.
eval "exec $_lockfd<&-"