v1cont / yad

Yet Another Dialog
GNU General Public License v3.0
665 stars 58 forks source link

yad --form --field="" leaves STDIN non-blocking #27

Open catb0t opened 5 years ago

catb0t commented 5 years ago
$ read 
(notice that read works)

$ yad  --form --field="" # input doesn't matter
|

$ read
bash: read: read error: 0: Resource temporarily unavailable

Using yad --form --field="" leaves STDIN fd 0 nonblocking, which read and many other programs cannot use. this also affects parent shells that run scripts in subshells

This is a bug because yad found stdin in a blocking state but didn't leave it that way. see http://gnu-bash.2382.n7.nabble.com/read-may-fail-due-to-nonblocking-stdin-td18519.html

Note, this doesn't happen with just yad --form.

I can only imagine the issue is in

https://github.com/v1cont/yad/blob/8957347fc6376bc4ec992adef078a7b53399850e/src/form.c#L629

where a GTK bug means that g_io_channel_shutdown doesn't fcntl(STDIN_FILENO, F_SETFD, ~O_NONBLOCK...) properly

The fact multiple while loops are used to poll whether to read again would suggest that ch was opened by GIO in non-blocking mode...

v1cont commented 5 years ago

sorry, i can't reproduce this behavior. check under both zsh 5.7 and bash 5

catb0t commented 5 years ago

This isn't present in zsh 5.5.1 either.

I'm using Bash 4.4, as are the vast majority of users in Debian/Fedora, since Bash 5 is a long way away due to the standard libreadline being v5 (Bash 5 needs readline 8) and libreadline is a pain in the ass to compile.

I think it should be fixed for older shells just because Bash 5 will have low adoption for a long time. Or is it a bash/upstream bug?

v1cont commented 5 years ago

checked under bash 4.3.48 on ubuntu 16.04.5 (all i can find at the moment). still can't reproduce

Misko-2083 commented 2 years ago

It's reproducible in bash 5.1 with cycle read.

    while : ; do
       date +"%a %d %b %H:%M %S"
       sleep 1
    done | { yad --title=clock --geometry=230x50+420+16 --form --cycle-read --field=": "; read var; }

close the dialog and type in something.

It happens only with external commands, with bash built-ins like printf and echo it works fine:

while : ; do
    printf '%(%a %d %b %H:%M %S)T\n'
        #   echo $(date +"%a %d %b %H:%M %S")
    sleep 1
done | { yad --title=clock --geometry=230x50+420+16 --form --cycle-read --field=": "; read var; }

Plus the while loop will run forever unless the builtin are used

    while : ; do
       date +"%a %d %b %H:%M %S"
       sleep 1
    done | yad --title=clock --geometry=230x50+420+16 --form --cycle-read --field=": "