lib/common.sh: lock, slock: Allow locks to be inherited.

Allow for locks to be inherited.  Inheriting the lock is something that
mkarchroot could do previously, but has since lost the ability to do.  This
allows for the programs to be more compos-able.

Do this by instead of unconditionally opening $file on $fd, first check if
$file is already open on $fd; and go ahead use it if it is.

The naive way of doing this would be to `$(readlink /dev/fd/$fd)` and
compare that to `$file`.  However, if `$file` is itself a symlink; or there
is a symlink somewhere in the path to `$file`, then this could easily fail.
Instead, check `[[ "/dev/fd/$fd" -ef "$file" ]]`.  Even though the Bash
documentation (`help test`) says that `-ef` checks for if the two files are
hard links to eachother, because it uses stat(3) (which resolves symlinks)
to do this check, it also works with the /dev/fd/ soft links.
This commit is contained in:
Luke Shumaker 2017-03-25 12:34:39 -04:00 committed by Jan Alexander Steffens (heftig)
parent 997bc1dc0d
commit d333440810
No known key found for this signature in database
GPG Key ID: A5E9288C4FA415FA
1 changed files with 10 additions and 2 deletions

View File

@ -138,7 +138,11 @@ get_full_version() {
# usage : lock( $fd, $file, $message )
##
lock() {
eval "exec $1>"'"$2"'
# Only reopen the FD if it wasn't handed to us
if ! [[ "/dev/fd/$1" -ef "$2" ]]; then
eval "exec $1>"'"$2"'
fi
if ! flock -n $1; then
stat_busy "$3"
flock $1
@ -150,7 +154,11 @@ lock() {
# usage : slock( $fd, $file, $message )
##
slock() {
eval "exec $1>"'"$2"'
# Only reopen the FD if it wasn't handed to us
if ! [[ "/dev/fd/$1" -ef "$2" ]]; then
eval "exec $1>"'"$2"'
fi
if ! flock -sn $1; then
stat_busy "$3"
flock -s $1