[pass] [PATCH] Locking clipboard restore.

Stephen Blott smblott at gmail.com
Sat Mar 22 14:29:26 CET 2014


---
 src/password-store.sh | 63 +++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 58 insertions(+), 5 deletions(-)

diff --git a/src/password-store.sh b/src/password-store.sh
index 3c9031d..0f1bc60 100755
--- a/src/password-store.sh
+++ b/src/password-store.sh
@@ -12,7 +12,6 @@ CLIP_TIME="${PASSWORD_STORE_CLIP_TIME:-45}"
 export GIT_DIR="${PASSWORD_STORE_GIT:-$PREFIX}/.git"
 export GIT_WORK_TREE="${PASSWORD_STORE_GIT:-$PREFIX}"
 
-
 version() {
 	cat <<_EOF
 |-----------------------|
@@ -107,6 +106,59 @@ set_gpg_recipients() {
 		gpg_recipient_args+=( "-r" "$gpg_id" )
 	done < "$current"
 }
+# Linux and FreeBSD have flock(1), Darwin and OS X seem not to, and for others?
+# Who knows. On systems without flock(1), this stub emulates the legacy
+# clip/restore behaviour.
+if ! which flock > /dev/null; then
+	flock() {
+		if [[ -z "$done_kill_of_sleepers" && -n "$sleep_argv0" ]]; then
+			pkill -f "^$sleep_argv0" 2>/dev/null && sleep 0.1
+			done_kill_of_sleepers="yes"
+		fi
+		true
+	}
+fi
+lock_start() {
+	lock_directory="password-store.$USER.locking"
+
+	if [[ -d /dev/shm && -w /dev/shm && -x /dev/shm ]]; then
+		# Lock files will not survive a system restart.
+		lock_directory="/dev/shm/$lock_directory"
+	else
+		# Lock files may or may not survive a system restart.
+		lock_directory="/tmp/$lock_directory"
+	fi
+
+	mkdir -p $lock_directory || exit 1
+   	display64=$(echo $DISPLAY | base64)
+	running_lock="$lock_directory/lock.running_lock.$display64"
+	stored_clipboard="$lock_directory/lock.stored_clipboard.$display64"
+
+	exec 8>>$running_lock 9>>$stored_clipboard
+	chmod 0600 $running_lock $stored_clipboard
+
+	flock --exclusive 9
+	if flock --exclusive --nonblock 8; then
+		# There are no active background processes.
+		xclip -o -selection "$SELECTION" | base64 > $stored_clipboard
+		flock --unlock 8
+	fi
+	flock --shared 8
+	flock --unlock 9
+}
+lock_end() {
+	flock --exclusive 9
+	if flock --exclusive --nonblock 8; then
+		# This is the last of any possible group of concurrent
+		# background processes.
+		cat $stored_clipboard
+		: > $stored_clipboard
+	else
+		# There are other background processes, leave it to one of them
+		# to restore the clipboard.
+		false
+	fi
+}
 
 #
 # BEGIN Platform definable
@@ -117,13 +169,14 @@ clip() {
 	# we're going with this for now.
 
 	sleep_argv0="password store sleep on display $DISPLAY"
-	pkill -f "^$sleep_argv0" 2>/dev/null && sleep 0.1
-	before="$(xclip -o -selection "$SELECTION" | base64)"
+	lock_start
 	echo -n "$1" | xclip -selection "$SELECTION"
+	password64="$(echo -n "$1" | base64)"
 	(
 		( exec -a "$sleep_argv0" sleep "$CLIP_TIME" )
-		now="$(xclip -o -selection "$SELECTION" | base64)"
-		[[ $now != $(echo -n "$1" | base64) ]] && before="$now"
+		before="$(lock_end)" || exit 0
+		now64="$(xclip -o -selection "$SELECTION" | base64)"
+		[[ "$now64" != "$password64" ]] && before="$now64"
 
 		# It might be nice to programatically check to see if klipper exists,
 		# as well as checking for other common clipboard managers. But for now,
-- 
1.9.0



More information about the Password-Store mailing list