[type/__package_opkg] Use mkdir(1) to lock instead of noclobber

noclobber is potentially unsafe, because it relies on the underlying shell to
implement noclobber in a safe way that avoids race conditions between multiple
processes.
mkdir is safer because it is mandated by POSIX to "fail" if the target already
exists.
This commit is contained in:
Dennis Camera 2020-06-24 08:47:22 +02:00
parent 3649555f35
commit a9778965be
1 changed files with 16 additions and 9 deletions

View File

@ -24,21 +24,28 @@
# #
readonly __type_path=${__object%%${__object_id}*} readonly __type_path=${__object%%${__object_id}*}
readonly LOCKFILE="${__type_path}/cdist_opkg.lock" test -d "${__type_path}" || { echo 'Cannot determine __type_path' >&2; exit 1; }
readonly LOCKDIR="${__type_path:?}/.cdist_opkg.lock.dir"
_lock() ( _lock() {
set -o noclobber until mkdir "${LOCKDIR:?}" 2>/dev/null
until echo $$>"${LOCKFILE}"
do do
while test -f "${LOCKFILE}"; do sleep 1; done while test -d "${LOCKDIR}"
do
# DEBUG: printf 'Locked by PID: %u\n' "$(cat "${LOCKDIR}/pid")"
sleep 1
done
done done
echo $$ >"${LOCKDIR:?}/pid"
) 2>/dev/null }
_unlock() { _unlock() {
if test -s "${LOCKFILE}" && test "$(cat "${LOCKFILE}")" = $$ test -d "${LOCKDIR}" || return 0
if test -s "${LOCKDIR}/pid"
then then
rm "${LOCKFILE}" test "$(cat "${LOCKDIR}/pid")" = $$ || return 1
rm "${LOCKDIR:?}/pid"
fi fi
rmdir "${LOCKDIR:?}"
} }