Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Child process hangs waiting for EOF (end fo file) when using stdin(Command.PIPED) #1463

Closed
ValdezFOmar opened this issue Aug 10, 2024 · 3 comments · Fixed by #1464
Closed
Labels
bug Something isn't working

Comments

@ValdezFOmar
Copy link

What system are you running Yazi on?

Linux X11

What terminal are you running Yazi in?

kitty 0.35.2

yazi --debug output

Yazi
    Version: 0.3.0 (36381e6 2024-08-10)
    Debug  : false
    OS     : linux-x86_64 (unix)

Ya
    Version: 0.3.0

Emulator
    Emulator.via_env: ("xterm-kitty", "")
    Emulator.via_csi: Ok(Kitty)
    Emulator.detect : Kitty

Adapter
    Adapter.matches: Kitty

Desktop
    XDG_SESSION_TYPE: Some("x11")
    WAYLAND_DISPLAY : None
    DISPLAY         : Some(":0")

SSH
    shared.in_ssh_connection: false

WSL
    /proc/sys/fs/binfmt_misc/WSLInterop: false

Variables
    SHELL              : Some("/usr/bin/bash")
    EDITOR             : Some("nvim")
    YAZI_FILE_ONE      : None
    YAZI_CONFIG_HOME   : None
    ZELLIJ_SESSION_NAME: None

Text Opener
    default: Some(Opener { run: "${EDITOR:-vi} \"$@\"", block: true, orphan: false, desc: "$EDITOR", for_: None, spread: true })
    block  : Some(Opener { run: "${EDITOR:-vi} \"$@\"", block: true, orphan: false, desc: "$EDITOR", for_: None, spread: true })

tmux
    TMUX   : false
    Version: No such file or directory (os error 2)

Dependencies
    file             : 5.45
    ueberzugpp       : No such file or directory (os error 2)
    ffmpegthumbnailer: No such file or directory (os error 2)
    magick           : No such file or directory (os error 2)
    fzf              : 0.54.3
    fd               : 10.1.0
    rg               : 14.1.0
    chafa            : No such file or directory (os error 2)
    zoxide           : No such file or directory (os error 2)
    7z               : 17.05
    7zz              : No such file or directory (os error 2)
    jq               : No such file or directory (os error 2)


--------------------------------------------------

Did you try the latest nightly build to see if the problem got fixed?

Yes, and I updated the debug information above (yazi --debug) to the nightly that I tried

Describe the bug

When setting the stdin of a child process to be piped and spawning it (e.g. Command('rev'):stdin(Command.PIPED):spawn()) I can write to its input, but then process never completes. The task manager shows that the process is still open, it just has not exit and there's no error (even on the logs):

image

Minimal reproducer

Plugin at ~/.config/yazi/plugins/repro.yazi/init.lua

local function async_entry()
    local child = assert(Command('rev'):stdin(Command.PIPED):spawn())
    child:write_all('Hello world!\n')
    child:flush()
    local out = assert(child:wait_with_output())
    -- The process keeps wating for EOF and this line isn't reached
    ya.err(out.stdout)
end

return { entry = async_entry }

Keymap:

[[manager.append_keymap]]
on = '<C-l>'
run = 'plugin repro'

Anything else?

The example from the documentation works as expected, so I suspected that maybe what is causing the problem is that stdin is not being closed, thus the process doesn't reach the EOF and it just hangs there waiting for more data. The example from the docs works because as soon as echo exits, its stdout stream is closed and the piped stdin of rev reaches the EOF.

I try searching in the docs if there's a Child:close() method to manually close stdin but it seems that this functionality doesn't exists (even though there's write_all and flush methods). Maybe provide a close() method to close stdin so the child process can reach the EOF?

@sxyazi
Copy link
Owner

sxyazi commented Aug 11, 2024

Nice catch! Should be fixed in #1464

BTW you need to specify the stdout(Command.PIPED) if you want to retrieve back the stdout:

- local child = assert(Command('rev'):stdin(Command.PIPED):spawn())
+ local child = assert(Command('rev'):stdin(Command.PIPED):stdout(Command.PIPED):spawn())

@ValdezFOmar
Copy link
Author

It works now, thanks!
And yes, I was to focus with the stdin that I forgot about piping stdout, thanks for the remainder.

Copy link

I'm going to lock this issue because it has been closed for 30 days. ⏳
This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 11, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants