From 860387d2f206818fb839ab46bf4f0b1802954e8b Mon Sep 17 00:00:00 2001
From: romkatv <roman.perepelitsa@gmail.com>
Date: Sun, 17 Mar 2019 13:32:25 +0100
Subject: pull upstream changes from gitstatus

---
 gitstatus/bin/gitstatusd-darwin-x86_64 | Bin 969616 -> 969656 bytes
 gitstatus/bin/gitstatusd-freebsd-amd64 | Bin 2895504 -> 2895576 bytes
 gitstatus/bin/gitstatusd-linux-armv7l  | Bin 1713676 -> 1713676 bytes
 gitstatus/bin/gitstatusd-linux-x86_64  | Bin 2118928 -> 2123024 bytes
 gitstatus/gitstatus.plugin.zsh         |  97 ++++++++++++++-------------------
 5 files changed, 41 insertions(+), 56 deletions(-)

diff --git a/gitstatus/bin/gitstatusd-darwin-x86_64 b/gitstatus/bin/gitstatusd-darwin-x86_64
index 95747f4f..b8087e25 100755
Binary files a/gitstatus/bin/gitstatusd-darwin-x86_64 and b/gitstatus/bin/gitstatusd-darwin-x86_64 differ
diff --git a/gitstatus/bin/gitstatusd-freebsd-amd64 b/gitstatus/bin/gitstatusd-freebsd-amd64
index 2cafbcd6..cdca91c7 100755
Binary files a/gitstatus/bin/gitstatusd-freebsd-amd64 and b/gitstatus/bin/gitstatusd-freebsd-amd64 differ
diff --git a/gitstatus/bin/gitstatusd-linux-armv7l b/gitstatus/bin/gitstatusd-linux-armv7l
index b96215d0..c7df7534 100755
Binary files a/gitstatus/bin/gitstatusd-linux-armv7l and b/gitstatus/bin/gitstatusd-linux-armv7l differ
diff --git a/gitstatus/bin/gitstatusd-linux-x86_64 b/gitstatus/bin/gitstatusd-linux-x86_64
index 536f39df..5d19d2b8 100755
Binary files a/gitstatus/bin/gitstatusd-linux-x86_64 and b/gitstatus/bin/gitstatusd-linux-x86_64 differ
diff --git a/gitstatus/gitstatus.plugin.zsh b/gitstatus/gitstatus.plugin.zsh
index 966b24be..b44b8ef3 100644
--- a/gitstatus/gitstatus.plugin.zsh
+++ b/gitstatus/gitstatus.plugin.zsh
@@ -1,4 +1,5 @@
-[[ -o interactive ]] && autoload -Uz add-zsh-hook && zmodload zsh/datetime || return
+[[ -o interactive ]] || return
+ autoload -Uz add-zsh-hook && zmodload zsh/datetime && zmodload zsh/system || return
 
 # Retrives status of a git repo from a directory under its working tree.
 #
@@ -44,11 +45,13 @@
 # The point of reporting -1 as unstaged and untracked is to allow the command to skip scanning
 # files in large repos. See -m flag of gitstatus_start.
 #
+# gitstatus_query returns an error if gitstatus_start hasn't been called in the same shell or
+# failed.
+#
 #       !!!!! WARNING: CONCURRENT CALLS WITH THE SAME NAME ARE NOT ALLOWED !!!!!
 #
-# It's illegal to call `gitstatus_query NAME` if `gitstatus_query NAME` is running concurrently in
-# the same interactive shell or its child, or if the callback for the last timed out request hasn't
-# fired yet. If you need to issue concurrent requests, use different NAME arguments.
+# It's illegal to call gitstatus_query if the last asynchronous call with the same NAME hasn't
+# completed yet. If you need to issue concurrent requests, use different NAME arguments.
 function gitstatus_query() {
   emulate -L zsh
   setopt err_return no_unset
@@ -72,29 +75,12 @@ function gitstatus_query() {
 
   [[ -v GITSTATUS_DAEMON_PID_${name} ]]
 
-  local -i req_fd
-  local req_fd_var=_GITSTATUS_REQ_FD_${name}
+  # Verify that gitstatus_query is running in the same process that ran gitstatus_start.
   local client_pid_var=_GITSTATUS_CLIENT_PID_${name}
+  [[ ${(P)client_pid_var} == $$ ]]
 
-  [[ ${(P)client_pid_var} == $$ ]] && {
-    req_fd=${(P)req_fd_var}
-  } || {
-    local req_fifo_var=_GITSTATUS_REQ_FIFO_${name}
-    local resp_fifo_var=_GITSTATUS_RESP_FIFO_${name}
-    local resp_fd_var=_GITSTATUS_RESP_FD_${name}
-    local -i resp_fd
-    exec {req_fd}<>${(P)req_fifo_var}
-    exec {resp_fd}<>${(P)resp_fifo_var}
-    typeset -g $client_pid_var=$$
-    typeset -g $req_fd_var=$req_fd
-    typeset -g $resp_fd_var=$resp_fd
-    typeset -giH $client_pid_var=$client_pid
-    function _gitstatus_process_response_${name}() {
-      _gitstatus_process_response ${${(%)${:-%N}}#_gitstatus_process_response_} 0 ''
-    }
-    zle -F $resp_fd _gitstatus_process_response_${name}
-  }
-
+  local req_fd_var=_GITSTATUS_REQ_FD_${name}
+  local -i req_fd=${(P)req_fd_var}
   local -r req_id="$EPOCHREALTIME"
   echo -nE "${req_id} ${callback}"$'\x1f'"${dir}"$'\x1e' >&$req_fd
 
@@ -106,7 +92,7 @@ function gitstatus_query() {
   [[ $VCS_STATUS_RESULT != tout || -n $callback ]]
 }
 
-typeset -fH _gitstatus_process_response() {
+function _gitstatus_process_response() {
   emulate -L zsh
   setopt err_return no_unset
 
@@ -172,8 +158,7 @@ typeset -fH _gitstatus_process_response() {
 #             Negative value means infinity. Defaults to -1.
 function gitstatus_start() {
   emulate -L zsh
-  setopt err_return no_unset
-  unsetopt bg_nice
+  setopt err_return no_unset no_bg_nice
 
   local opt
   local -F timeout=5
@@ -200,24 +185,31 @@ function gitstatus_start() {
   local daemon && daemon=${GITSTATUS_DAEMON:-${${(%):-%x}:A:h}/bin/gitstatusd-${os:l}-${arch:l}}
   [[ -f $daemon ]] || { echo "file not found: $daemon" >&2 && return 1 }
 
-  local req_fifo resp_fifo log
-  local -i req_fd=-1 resp_fd=-1 daemon_pid=-1
+  local lock_file req_fifo resp_fifo log_file
+  local -i lock_fd=-1 req_fd=-1 resp_fd=-1 daemon_pid=-1
 
   function start() {
+    lock_file=$(mktemp "${TMPDIR:-/tmp}"/gitstatus.$$.lock.XXXXXXXXXX)
+    zsystem flock -f lock_fd $lock_file
+
     req_fifo=$(mktemp -u "${TMPDIR:-/tmp}"/gitstatus.$$.pipe.req.XXXXXXXXXX)
-    resp_fifo=$(mktemp -u "${TMPDIR:-/tmp}"/gitstatus.$$.pipe.resp.XXXXXXXXXX)
     mkfifo $req_fifo
+    sysopen -rw -o cloexec -u req_fd $req_fifo
+    command rm -f $req_fifo
+
+    resp_fifo=$(mktemp -u "${TMPDIR:-/tmp}"/gitstatus.$$.pipe.resp.XXXXXXXXXX)
     mkfifo $resp_fifo
-    exec {req_fd}<>$req_fifo
-    exec {resp_fd}<>$resp_fifo
+    sysopen -rw -o cloexec -u resp_fd $resp_fifo
+    command rm -f $resp_fifo
+
     function _gitstatus_process_response_${name}() {
       _gitstatus_process_response ${${(%)${:-%N}}#_gitstatus_process_response_} 0 ''
     }
     zle -F $resp_fd _gitstatus_process_response_${name}
 
     [[ ${GITSTATUS_ENABLE_LOGGING:-0} == 1 ]] &&
-      log=$(mktemp "${TMPDIR:-/tmp}"/gitstatus.$$.log.XXXXXXXXXX) ||
-      log=/dev/null
+      log_file=$(mktemp "${TMPDIR:-/tmp}"/gitstatus.$$.log.XXXXXXXXXX) ||
+      log_file=/dev/null
 
     local -i threads=${GITSTATUS_NUM_THREADS:-0}
     (( threads > 0)) || {
@@ -228,48 +220,41 @@ function gitstatus_start() {
     }
 
     # We use `zsh -c` instead of plain {} or () to work around bugs in zplug. It hangs on startup.
-    zsh -c "
-      ${(q)daemon} --parent-pid=$$ --dirty-max-index-size=${(q)max_dirty} --num-threads=$threads
+    zsh -xc "
+      ${(q)daemon} --lock-fd=3 --dirty-max-index-size=$max_dirty --num-threads=$threads
       echo -nE $'bye\x1f0\x1e'
-      command rm -f ${(q)req_fifo} ${(q)resp_fifo}
-    " <&$req_fd >&$resp_fd 2>$log &!
+    " <&$req_fd >&$resp_fd 2>$log_file 3<$lock_file &!
 
     daemon_pid=$!
+    command rm -f $lock_file
 
     local reply
     echo -nE $'hello\x1f\x1e' >&$req_fd
     IFS='' read -r -d $'\x1e' -u $resp_fd -t $timeout reply
     [[ $reply == $'hello\x1f0' ]]
 
-    function _gitstatus_cleanup_${name}() {
+    function _gitstatus_cleanup_${daemon_pid}() {
       emulate -L zsh
-      local name=${${(%)${:-%N}}#_gitstatus_cleanup_}
-      local daemon_pid_var=GITSTATUS_DAEMON_PID_${name}
-      local req_fifo_var=_GITSTATUS_REQ_FIFO_${name}
-      local resp_fifo_var=_GITSTATUS_RESP_FIFO_${name}
-      local -i daemon_pid=${(P)daemon_pid_var}
-      local req_fifo=${(P)req_fifo_var}
-      local resp_fifo=${(P)resp_fifo_var}
-      [[ $daemon_pid -ge 0 ]] && kill -- -$daemon_pid &>/dev/null
-      command rm -f $req_fifo $resp_fifo
+      setopt err_return no_unset
+      local -i daemon_pid=${${(%)${:-%N}}#_gitstatus_cleanup_}
+      kill -- -$daemon_pid &>/dev/null || true
     }
-    add-zsh-hook zshexit _gitstatus_cleanup_${name}
+    add-zsh-hook zshexit _gitstatus_cleanup_${daemon_pid}
   }
 
   start && {
-    typeset -g    GITSTATUS_DAEMON_LOG_${name}=$log
+    typeset -g    GITSTATUS_DAEMON_LOG_${name}=$log_file
     typeset -gi   GITSTATUS_DAEMON_PID_${name}=$daemon_pid
-    typeset -gH  _GITSTATUS_REQ_FIFO_${name}=$req_fifo
-    typeset -gH  _GITSTATUS_RESP_FIFO_${name}=$resp_fifo
     typeset -giH _GITSTATUS_REQ_FD_${name}=$req_fd
     typeset -giH _GITSTATUS_RESP_FD_${name}=$resp_fd
     typeset -giH _GITSTATUS_CLIENT_PID_${name}=$$
   } || {
-    echo "gitstatus failed to initialize" >&2
-    [[ $daemon_pid -ge 0 ]] && kill -- -$daemon_pid &>/dev/null || true
+    echo "gitstatus failed to initialize" >&2 || true
+    [[ $daemon_pid -gt 0 ]] && kill -- -$daemon_pid &>/dev/null || true
+    [[ $lock_fd -ge 0 ]] && zsystem flock -u $lock_fd || true
     [[ $req_fd -ge 0 ]] && exec {req_fd}>&- || true
     [[ $resp_fd -ge 0 ]] && { zle -F $resp_fd || true } && { exec {resp_fd}>&- || true}
-    command rm -f $req_fifo $resp_fifo
+    command rm -f $lock_file $req_fifo $resp_fifo || true
     return 1
   }
 }
-- 
cgit v1.2.3