Blame maint/pipestatus

Packit Service c5cf8c
# -*- mode: sh; -*-
Packit Service c5cf8c
Packit Service c5cf8c
#
Packit Service c5cf8c
# Public domain
Packit Service c5cf8c
#
Packit Service c5cf8c
# Written by Aleksey Cheusov <vle@gmx.net>
Packit Service c5cf8c
# based on the code from FAQ of comp.unix.shell newsgroup
Packit Service c5cf8c
#
Packit Service c5cf8c
# Set of shell functions for running pipe and checking
Packit Service c5cf8c
# exit status of ALL programs, not only last one.
Packit Service c5cf8c
#
Packit Service c5cf8c
# Version 0.6.0
Packit Service c5cf8c
#
Packit Service c5cf8c
Packit Service c5cf8c
# 
Packit Service c5cf8c
__shquote (){
Packit Service c5cf8c
    __cmd=`printf '%s\n' "$1" | sed "s|'|'\\\\\''|g"`
Packit Service c5cf8c
    printf "%s\n" "'$__cmd'"
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
__pipestatus_err_msg (){
Packit Service c5cf8c
    if test "$PIPESTATUS_VERBOSE"; then
Packit Service c5cf8c
	echo "Pipe failed, pipestatus_all='$pipestatus_all'" 1>&2
Packit Service c5cf8c
    fi
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
# run pipe and set pipestatus_1, pipestatus_2, ... and pipesize variables
Packit Service c5cf8c
# Example: runpipe_base prog1 arg11 arg12 '|' prog2 arg21 arg22 '|' prog3
Packit Service c5cf8c
# Always return zero exit status
Packit Service c5cf8c
runpipe_base (){
Packit Service c5cf8c
    #
Packit Service c5cf8c
    pipesize=0
Packit Service c5cf8c
Packit Service c5cf8c
    # whole command
Packit Service c5cf8c
    __pipestatus_com=
Packit Service c5cf8c
Packit Service c5cf8c
    # token count
Packit Service c5cf8c
    __pipestatus_k=1
Packit Service c5cf8c
Packit Service c5cf8c
    # program in pipe (between |)
Packit Service c5cf8c
    __pipestatus_l=
Packit Service c5cf8c
Packit Service c5cf8c
    # counter
Packit Service c5cf8c
    __pipestatus_j=1
Packit Service c5cf8c
Packit Service c5cf8c
    # generating whole command
Packit Service c5cf8c
    for __pipestatus_a in "$@"; do
Packit Service c5cf8c
        if [ "_$__pipestatus_a" = '_|' ]; then
Packit Service c5cf8c
            __pipestatus_com="$__pipestatus_com {
Packit Service c5cf8c
   if $__pipestatus_l 3>&-"'; then
Packit Service c5cf8c
      echo "pipestatus_'$__pipestatus_j'=0" 1>&3
Packit Service c5cf8c
   else
Packit Service c5cf8c
      echo "pipestatus_'$__pipestatus_j'=$?" 1>&3
Packit Service c5cf8c
   fi
Packit Service c5cf8c
} 4>&- |
Packit Service c5cf8c
'
Packit Service c5cf8c
            __pipestatus_j=`expr $__pipestatus_j + 1`
Packit Service c5cf8c
	    __pipestatus_l=
Packit Service c5cf8c
        else
Packit Service c5cf8c
            __pipestatus_l="$__pipestatus_l `__shquote \"$__pipestatus_a\"`"
Packit Service c5cf8c
        fi
Packit Service c5cf8c
        __pipestatus_k=`expr $__pipestatus_k + 1`
Packit Service c5cf8c
    done
Packit Service c5cf8c
    __pipestatus_com="if $__pipestatus_com $__pipestatus_l 3>&- 1>&4 4>&-"'; then
Packit Service c5cf8c
      echo "pipestatus_'"$__pipestatus_j"'=0"
Packit Service c5cf8c
   else
Packit Service c5cf8c
      echo "pipestatus_'"$__pipestatus_j"'=$?"
Packit Service c5cf8c
   fi'
Packit Service c5cf8c
Packit Service c5cf8c
    #
Packit Service c5cf8c
#    echo "$__pipestatus_com"
Packit Service c5cf8c
Packit Service c5cf8c
    # '|| true' - trick for 'set -e'
Packit Service c5cf8c
    exec 4>&1 
Packit Service c5cf8c
    eval `exec 3>&1; eval "$__pipestatus_com" || true`
Packit Service c5cf8c
    exec 4>&- 
Packit Service c5cf8c
Packit Service c5cf8c
    #
Packit Service c5cf8c
    pipesize=$__pipestatus_j
Packit Service c5cf8c
Packit Service c5cf8c
    # pipestatus_all
Packit Service c5cf8c
    __pipestatus_j=2
Packit Service c5cf8c
    pipestatus_all=$pipestatus_1
Packit Service c5cf8c
    while [ "$__pipestatus_j" -le "$pipesize" 2>/dev/null ]; do
Packit Service c5cf8c
	eval "pipestatus_all=\"$pipestatus_all \$pipestatus_$__pipestatus_j\""
Packit Service c5cf8c
        __pipestatus_j=`expr $__pipestatus_j + 1`
Packit Service c5cf8c
    done
Packit Service c5cf8c
Packit Service c5cf8c
    return 0
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
# returns zero exit status if ALL progs in pipe return zero
Packit Service c5cf8c
check_status0 (){
Packit Service c5cf8c
    __pipestatus_j=1
Packit Service c5cf8c
    while [ "$__pipestatus_j" -le "$pipesize" ]; do
Packit Service c5cf8c
	eval "[ \$pipestatus_$__pipestatus_j -eq 0 ]" || {
Packit Service c5cf8c
	    __pipestatus_err_msg
Packit Service c5cf8c
	    return 1
Packit Service c5cf8c
	}
Packit Service c5cf8c
	__pipestatus_j=`expr $__pipestatus_j + 1`
Packit Service c5cf8c
    done
Packit Service c5cf8c
Packit Service c5cf8c
    return 0
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
# returns zero exit status if ALL progs in pipe return zero
Packit Service c5cf8c
runpipe0 (){
Packit Service c5cf8c
    runpipe_base "$@"
Packit Service c5cf8c
    check_status0
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
# match all statuses with the pattern
Packit Service c5cf8c
# example: check_status_re '0 . 0'
Packit Service c5cf8c
# . means "any status"
Packit Service c5cf8c
check_status_re (){
Packit Service c5cf8c
    __pipestatus_re=`echo $1 | sed 's/[.]/[0-9][0-9]*/g'`
Packit Service c5cf8c
    __pipestatus_j=1
Packit Service c5cf8c
    __pipestatus_ps=
Packit Service c5cf8c
    while [ "$__pipestatus_j" -le "$pipesize" ]; do
Packit Service c5cf8c
	eval '__pipestatus_ps="$__pipestatus_ps ${pipestatus_'$__pipestatus_j'}"'
Packit Service c5cf8c
	__pipestatus_j=`expr $__pipestatus_j + 1`
Packit Service c5cf8c
    done
Packit Service c5cf8c
Packit Service c5cf8c
    # trick for set -e
Packit Service c5cf8c
    if echo "$__pipestatus_ps" | grep -E "^ $__pipestatus_re"'$' > /dev/null
Packit Service c5cf8c
    then
Packit Service c5cf8c
	__pipestatus_ret=0
Packit Service c5cf8c
    else
Packit Service c5cf8c
	__pipestatus_ret=$?
Packit Service c5cf8c
	__pipestatus_err_msg
Packit Service c5cf8c
    fi
Packit Service c5cf8c
Packit Service c5cf8c
    # egrep not found?
Packit Service c5cf8c
    case "$__pipestatus_ret" in
Packit Service c5cf8c
	0|1)
Packit Service c5cf8c
	    ;;
Packit Service c5cf8c
	*)
Packit Service c5cf8c
	    exit 2; # fatal error with egrep
Packit Service c5cf8c
    esac
Packit Service c5cf8c
Packit Service c5cf8c
    return $__pipestatus_ret
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
# match all statuses with the pattern
Packit Service c5cf8c
# example: runpipe_re '0 . 0' prog1 '|' prog2 '|' prog3
Packit Service c5cf8c
# . means "any status"
Packit Service c5cf8c
runpipe_re (){
Packit Service c5cf8c
    __pipestatus_re="$1"
Packit Service c5cf8c
    shift
Packit Service c5cf8c
Packit Service c5cf8c
    runpipe_base "$@"
Packit Service c5cf8c
    check_status_re "$__pipestatus_re"
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
# return exit code of the last program in pipe
Packit Service c5cf8c
check_status (){
Packit Service c5cf8c
    eval return '$pipestatus_'${pipesize}
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
# similar to plain pipe but set 'pipestatus_XX' and 'pipesize' variables
Packit Service c5cf8c
runpipe (){
Packit Service c5cf8c
    runpipe_base "$@"
Packit Service c5cf8c
    check_status
Packit Service c5cf8c
}