Reviewed-by: Kostiantyn Kostiuk <[email protected]>

Cool magic

On Tue, Mar 17, 2026 at 11:48 AM Peter Maydell <[email protected]>
wrote:

> PIPESTATUS is a bash-specific construct, and this script is supposed
> to be POSIX shell. We only use it in one place, to capture the exit
> status of a command whose output we are piping to 'logger'.
>
> Replace the PIPESTATUS usage with the trick described in
>
> https://unix.stackexchange.com/questions/14270/get-exit-status-of-process-thats-piped-to-another/70675#70675
> which uses a command-group to capture the status of the
> first process in the pipeline.
>
> Cc: [email protected]
> Fixes: 85978dfb6b1c133 ("qemu-ga: Optimize freeze-hook script logic of
> logging error")
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3339
> Signed-off-by: Peter Maydell <[email protected]>
> ---
>  scripts/qemu-guest-agent/fsfreeze-hook | 19 +++++++++++++++++--
>  1 file changed, 17 insertions(+), 2 deletions(-)
>
> diff --git a/scripts/qemu-guest-agent/fsfreeze-hook
> b/scripts/qemu-guest-agent/fsfreeze-hook
> index 6e2d7588af..21eb5c5145 100755
> --- a/scripts/qemu-guest-agent/fsfreeze-hook
> +++ b/scripts/qemu-guest-agent/fsfreeze-hook
> @@ -47,8 +47,23 @@ for file in "$FSFREEZE_D"/* ; do
>          "$file" "$@" >>"$LOGFILE" 2>&1
>          STATUS=$?
>      else
> -        "$file" "$@" 2>&1 | logger -t qemu-ga-freeze-hook
> -        STATUS=${PIPESTATUS[0]}
> +        # We want to pipe the output of $file through 'logger' and also
> +        # capture its exit status. Since we are a POSIX script we can't
> +        # use PIPESTATUS, so instead this is a trick borrowed from
> +        #
> https://unix.stackexchange.com/questions/14270/get-exit-status-of-process-thats-piped-to-another/70675#70675
> +        # which uses command-groups and redirection to get the exit
> status.
> +        # This is equivalent to
> +        #   "$file" "$@" 2>&1 | logger -t qemu-ga-freeze-hook
> +        # plus setting the exit status of the pipe to the exit
> +        # status of the first command rather than the last one.
> +        { { { {
> +                "$file" "$@" 2>&1 3>&- 4>&-
> +                echo $? >&3
> +            } | logger -t qemu-ga-freeze-hook >&4
> +            } 3>&1
> +          } | { read -r xs ; exit "$xs"; }
> +        } 4>&1
> +        STATUS=$?
>      fi
>
>      if [ "$STATUS" -ne 0 ]; then
> --
> 2.43.0
>
>

Reply via email to