From 8dc2e86c2e67268d12b726083436b668ab0993c9 Mon Sep 17 00:00:00 2001 From: Adam Monsen Date: Fri, 8 Mar 2013 10:53:54 -0800 Subject: [PATCH] j.sh: add locking Description and repro: If several processes simultaneously try to read and write the datafile, you may wind up with an empty datafile. I noticed this when opening up many shells at once with `screen -c dev`, where `dev` contains: source /etc/screenrc screen -t home chdir /tmp screen -t tmp1 screen -t tmp2 screen -t tmp3 screen -t tmp4 screen -t tmp5 In one or more of the screen windows I see mv: cannot stat `/home/adamm/.j.tmp': No such file or directory and I notice my datafile has been truncated. --- j.sh | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/j.sh b/j.sh index b8d37bd..6be8948 100644 --- a/j.sh +++ b/j.sh @@ -2,10 +2,16 @@ j() { local datafile=$HOME/.j + exec 9>$HOME/.j.lock + flock --timeout 5 9 if [ "$1" = "--add" ]; then shift # $HOME isn't worth matching - [ "$*" = "$HOME" ] && return + if [ "$*" = "$HOME" ] + then + flock -u 9 + return + fi awk -v q="$*" -v t="$(date +%s)" -F"|" ' BEGIN { l[q] = 1; d[q] = t } $2 >= 1 { @@ -36,11 +42,20 @@ j() { ' $datafile 2>/dev/null else # list/go (must set $JPY) - [ -f "$JPY" ] || return + if ! [ -f "$JPY" ] + then + flock -u 9 + return + fi cd="$($JPY -f $datafile $*)" - [ -z "$cd" -o "$cd" = "$PWD" ] && return + if [ -z "$cd" -o "$cd" = "$PWD" ] + then + flock -u 9 + return + fi cd "$cd" fi + flock -u 9 } # tab completion (only works in bash for now) [ "$SHELL" = "/bin/bash" ] && complete -C 'j --complete "$COMP_LINE"' j