#!/bin/sh # svn wrapper to avoid "svn: Write error: Broken pipe" error messages # when piping the svn output to some command. This is a workaround to # the following bug: # # http://subversion.tigris.org/issues/show_bug.cgi?id=3014 # # Note: the svnwrapper:term trick prevents this script from freezing # if svn starts a background process via $SVN_SSH (e.g. ssh -fMN ... # for connection sharing) that still has its stderr connected to the # pipe after svn terminates. # # This version supports lines sent to stderr not terminated with a # newline character, such as prompts. Prompts should be sent to the # terminal instead of stderr, but svn is currently buggy: # # http://subversion.tigris.org/issues/show_bug.cgi?id=1117 # # Bug: zsh sometimes exits with exit status 141 while there hasn't been # a broken pipe, e.g.: # # prunille:~/wd> up # U db/bugs/debian.xml # Updated to revision 42990. # zsh: exit 141 # prunille:~/wd[PIPE]> # # where "up" is a zsh function that does # # svnwrapper up "$@" # # after a test. This happens under both GNU/Linux and Mac OS X. # # Script written by Vincent Lefevre in August 2010, # released in the public domain. # Use the -f zsh option so that the .zshenv file is not sourced, # in order to make sure that the environment under which svn is # run (in particular $SVN_SSH) is unchanged. [ -n "$ZSH_VERSION" ] || exec zsh -f -- "$0" ${1+"$@"} filter() { unset brpipe while true do unset line timeout while read -r $timeout -k -u 0 ch do line="$line$ch" [[ $ch = $'\012' ]] && break timeout=(-t 0.1) done case $line in svnwrapper:term$'\012') break ;; *Broken\ pipe$'\012') brpipe=1 ;; ?*) printf "%s" "$line" >&2 ;; *) break ;; # empty line (end of file) - parent has died? esac done # The "sleep 5" is there to avoid a rare race condition (it occurred # once): make sure the parent process receives the PIPE signal before # the filter process terminates (which can yield a SIGPIPE in svn). [[ -z $brpipe ]] || { kill -PIPE $$; sleep 5 } } { svn "$@"; st=$?; echo "svnwrapper:term" >&2 } 2>>(filter) exit $st # local variables: # mode: sh # eval: (sh-set-shell "zsh") # end: # # $Id: svnwrapper.zsh 44005 2011-05-28 23:09:16Z vinc17/ypig $