X-Git-Url: https://git.plutz.net/?p=cgilite;a=blobdiff_plain;f=storage.sh;h=22e6accbcba7cddd75bbaec0235a174b4aa53bd3;hp=a8484b0514891fe3e7d6f3cfdbb55fba655cb61a;hb=e02243e96d7cc400b63c3e856d0e80d4140c6805;hpb=e3e5c0d0a56dc4de4f7f9e0133e93b2360365eea diff --git a/storage.sh b/storage.sh index a8484b0..22e6acc 100755 --- a/storage.sh +++ b/storage.sh @@ -1,6 +1,6 @@ #!/bin/sh -# Copyright 2018, 2019 Paul Hänsch +# Copyright 2018, 2019, 2021 Paul Hänsch # # This is a file format helper, part of CGIlite. # @@ -25,41 +25,40 @@ BR=' ' LOCK(){ - local lock timeout block - lock="${1}.lock" - timeout="${2-20}" - if [ \! -w "${lock%/*}" ] || [ -e "$lock" -a \! -d "$lock" ]; then + local lock="${1}.lock" timeout="${2-20}" block + + if [ \! -w "${lock%/*}" ] || [ -e "$lock" -a \! -f "$lock" ]; then debug "Impossible to get lock: $lock" return 1 fi - while ! mkdir "$lock" 2>&-; do - block="$(cat "$lock/pid" || printf 1)" - if ! { ps -eo pid |grep -qwF "$block"; }; then - debug "Overriding stale lock: $lock" - break - fi - if [ $timeout -le 0 ]; then - debug "Timeout while trying to get lock: $lock" - return 1 + while [ $timeout -gt 0 ]; do + printf '%i\n' $$ >>"${lock}" + read block <"$lock" + if [ "$block" = $$ ]; then + return 0 + elif ! { ps -eo pid |grep -qwF "$block"; }; then + debug "Trying to override stale lock: $lock" + if LOCK "$lock" 1; then + rm -- "$lock" + RELEASE "$lock" + fi + else + timeout=$((timeout - 1)) + [ $timeout -gt 0 ] && sleep 1 fi - timeout=$((timeout - 1)) - sleep 1 done - printf '%i\n' $$ >"${lock}/pid" - return 0 + + debug "Timeout while trying to get lock: $lock" + return 1 } RELEASE(){ - local lock - lock="${1}.lock" - if [ "$(cat "$lock/pid")" = "$$" ]; then - rm "$lock/pid" - if ! rmdir "$lock"; then - debug "Cannot remove tainted lock: $lock" - printf '%i\n' $$ >"${lock}/pid" - return 1 - fi + local lock="${1}.lock" block + + read block <"$lock" + if [ "$block" = $$ ]; then + rm -- "$lock" return 0 else debug "Refusing to release foreign lock: $lock" @@ -67,20 +66,6 @@ RELEASE(){ fi } -STRING=' - s;\\;\\\\;g; - s;\n;\\n;g; - s;\t;\\t;g; - s;\r;\\r;g; - s;\+;\\+;g; - s; ;+;g; -' - -STRING_OLD(){ - { [ $# -eq 0 ] && cat || printf %s "$*"; } \ - | sed -E ':X; $!{N;bX;}'"$STRING" -} - STRING(){ local in out='' [ $# -gt 0 ] && in="$*" || in="$(cat)" @@ -93,24 +78,9 @@ STRING(){ " "*) out="${out}+"; in="${in# }" ;; *) out="${out}${in%%[\\${CR}${BR} + ]*}"; in="${in#"${in%%[\\${BR}${CR} + ]*}"}" ;; esac; done - printf '%s' "$out" + printf '%s' "${out:-\\}" } - -UNSTRING=' - :UNSTRING_X - s;((^|[^\\])(\\\\)*)\\n;\1\n;g; - s;((^|[^\\])(\\\\)*)\\t;\1\t;g; - s;((^|[^\\])(\\\\)*)\\r;\1\r;g; - s;((^|[^\\])(\\\\)*)\+;\1 ;g; - tUNSTRING_X; - s;((^|[^\\])(\\\\)*)\\\+;\1+;g; - s;\\\\;\\;g; -' -UNSTRING_OLD(){ - { [ $# -eq 0 ] && cat || printf %s "$*"; } \ - | sed -E "$UNSTRING" -} UNSTRING(){ local in out='' [ $# -gt 0 ] && in="$*" || in="$(cat)" @@ -119,12 +89,12 @@ UNSTRING(){ \\n*) out="${out}${BR}"; in="${in#\\n}" ;; \\r*) out="${out}${CR}"; in="${in#\\r}" ;; \\t*) out="${out} "; in="${in#\\t}" ;; - \\+) out="${out}+"; in="${in#\\+}" ;; + \\+*) out="${out}+"; in="${in#\\+}" ;; +*) out="${out} "; in="${in#+}" ;; \\*) in="${in#\\}" ;; *) out="${out}${in%%[\\+]*}"; in="${in#"${in%%[\\+]*}"}" ;; esac; done - printf '%s' "$out" + printf '%s\n' "$out" } DBM() { @@ -175,7 +145,7 @@ DBM() { update|replace) k="$1" key="$(STRING "$1")" value="$(STRING "$2")" LOCK "$file" || return 1 - if ! DBM check "$k"; then + if ! DBM "$file" check "$k"; then RELEASE "$file" return 1 fi @@ -192,7 +162,7 @@ DBM() { append) key="$(STRING "$1")" value="$(STRING "$2")" LOCK "$file" || return 1 - if ! DBM check "$1"; then + if ! DBM "$file" check "$1"; then RELEASE "$file" return 1 fi