v1cont / yad

Yet Another Dialog
GNU General Public License v3.0
685 stars 57 forks source link

fix returning 0 when an error occurred #214

Closed step- closed 1 year ago

step- commented 1 year ago

Issue: run_command_sync can return 0 when g_spawn_command_line_sync didn't set its return value argument because it couldn't run the command. Fix: return 255 in run_thread in such a case.

step- commented 1 year ago

Here's what happened before this fix:

yad --form --field=:fbtn '@asdasdasd'
WARNING: Run command failed: Failed to execute child process “asdasdasd” (No such file or directory)

(yad:15442): GLib-CRITICAL **: 10:53:53.514: g_strsplit: assertion 'string != NULL' failed
[1]    15442 segmentation fault  yad --form --field=:fbtn '@asdasdasd'

I first noticed this issue while investigating https://github.com/v1cont/yad/issues/211#issuecomment-1380348241

v1cont commented 1 year ago

thanks for reporting but this is more complex problem. fixed in d7ded23

step- commented 1 year ago

There's another problem, a bigger one IMO. I can briefly describe it as "a longer-running process hijacks other processes", but you really have to see what I mean. Use this script but before you do, add a print statement after the while loop, something like g_fprintf (stderr, "DONE %s\n", d->cmd); then start playing with the script. For instance, click button 2 then quickly button 5. You will see that "DONE sleep 2" and "DONE sleep 5" are printed together after 5 seconds. Now do the opposite, press button 5 then button 2. This time you get "DONE sleep 2" after two seconds, as it should be, and "DONE sleep 5" after 5 seconds, as expected. If you press all buttons, from top to bottom, you will see that DONE messages are printed in reverse click order. My guess is there is a stack data structure somewhere onto which process executions are pushed and popped. I can't find an explanation for the bizarre hijacking ("sleep 5" makes "sleep 2" return after 5 seconds). I was studying the g_spawn_command_line_sync code in glib 2.58.1 when you made your commit...

sleeper.sh

#!/bin/bash -a

sleeper () { #$1-delay $2-indent
: "$2$1> `date +%T.%03N`"
    for (( i = 0; i < $1; i++ )); do
        : "$2$1 : $i"
        sleep 1
    done
: "$2<$1 `date +%T.%03N`"
}

#force_error=ERROR
yad \
    --center -on-top --use-interp="${force_error}bash -xc \"%s\"" --form \
    --field="@sleep  2:fbtn" "@sleeper  2 '  '" \
    --field="@sleep  3:fbtn" "@sleeper  3 '   '" \
    --field="@sleep  5:fbtn" "@sleeper  5 '     '" \
    --field="@sleep  8:fbtn" "@sleeper  8 '        '" \
    --field="@sleep 13:fbtn" "@sleeper 13 '             '" \
    --field="@sleep 21:fbtn" "@sleeper 21 '                          '" \
    --button=quit:0 --buttons-layout=center
v1cont commented 1 year ago

this looks like stream buffering issue. stdbuf -o0 yad ... must resolve this

step- commented 1 year ago

this looks like stream buffering issue. stdbuf -o0 yad ... must resolve this

I don't know. I replaced stdbuf -o0 yad and stdbuf -o0 -e0 yad in sleeper.sh script but neither makes a difference here. Maybe it also depends on glib version, kernel build options...