@@ -10,22 +10,20 @@ PROTOTYPE_SHIM_PATH="${SHIM_PATH}/.pyenv-shim"
1010# Create the shims directory if it doesn't already exist.
1111mkdir -p " $SHIM_PATH "
1212
13+ declare last_acquire_error
14+
1315acquire_lock () {
1416 # Ensure only one instance of pyenv-rehash is running at a time by
1517 # setting the shell's `noclobber` option and attempting to write to
1618 # the prototype shim file. If the file already exists, print a warning
1719 # to stderr and exit with a non-zero status.
1820 local ret
1921 set -o noclobber
20- echo > " $PROTOTYPE_SHIM_PATH " 2> | /dev/null || ret=1
22+ last_acquire_error= " $( { ( echo -n > " $PROTOTYPE_SHIM_PATH " ; ) 2>&1 1>&3 3>&1 - ; } 3>&1 ) " || ret=1
2123 set +o noclobber
2224 [ -z " ${ret} " ]
2325}
2426
25- # If we were able to obtain a lock, register a trap to clean up the
26- # prototype shim when the process exits.
27- trap release_lock EXIT
28-
2927remove_prototype_shim () {
3028 rm -f " $PROTOTYPE_SHIM_PATH "
3129}
@@ -39,11 +37,17 @@ if [ ! -w "$SHIM_PATH" ]; then
3937 exit 1
4038fi
4139
42- unset acquired
43- start=$SECONDS
44- while (( SECONDS <= start + ${PYENV_REHASH_TIMEOUT:- 60} )) ; do
45- if acquire_lock 2> /dev/null; then
40+ declare acquired tested_for_other_write_errors
41+ declare start=$SECONDS
42+ PYENV_REHASH_TIMEOUT=${PYENV_REHASH_TIMEOUT:- 60}
43+ while (( SECONDS <= start + PYENV_REHASH_TIMEOUT )) ; do
44+ if acquire_lock; then
4645 acquired=1
46+
47+ # If we were able to obtain a lock, register a trap to clean up the
48+ # prototype shim when the process exits.
49+ trap release_lock EXIT
50+
4751 break
4852 else
4953 # Landlock sandbox subsystem in the Linux kernel returns false information in access() as of 6.14.0,
@@ -53,7 +57,7 @@ while (( SECONDS <= start + ${PYENV_REHASH_TIMEOUT:-60} )); do
5357 # in a way that taxes the usual use case as little as possible.
5458 if [[ -z $tested_for_other_write_errors ]]; then
5559 ( t=" $( TMPDIR=" $SHIM_PATH " mktemp) " && rm " $t " ) && tested_for_other_write_errors=1 ||
56- { echo " pyenv: cannot rehash: $SHIM_PATH isnt writable" >&2 ; break ; }
60+ { echo " pyenv: cannot rehash: $SHIM_PATH isn't writable" >&2 ; break ; }
5761 fi
5862 # POSIX sleep(1) doesn't provide subsecond precision, but many others do
5963 sleep 0.1 2> /dev/null || sleep 1
6266
6367if [ -z " ${acquired} " ]; then
6468 if [[ -n $tested_for_other_write_errors ]]; then
65- echo " pyenv: cannot rehash: $PROTOTYPE_SHIM_PATH exists" >&2
69+ echo " pyenv: cannot rehash: couldn't acquire lock" \
70+ " $PROTOTYPE_SHIM_PATH for $PYENV_REHASH_TIMEOUT seconds. Last error message:" >&2
71+ echo " $last_acquire_error " >&2
6672 fi
6773 exit 1
6874fi
0 commit comments