-
Notifications
You must be signed in to change notification settings - Fork 2k
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
eval "man -k ." | fzf | read hangs on mac #6806
Comments
I can reproduce when running fish interactively, it seems like first Happens since 2fe2169 which made This workaround seems to restore the old behavior: begin; eval "man -k ."; end | fzf | read (or |
@ridiculousfish @mqudsi any thoughts? If the workaround is enough, I don't think this needs to be fixed for 3.1.*, though of course it would be nice. |
I thought this would be the same as #6624 but it doesn't appear to be. |
This ends up being similar to #6624 except we need to thread the pgid into eval as well. |
So the problems here are:
This points the way for a lot of cleanup - I think this should go into a patch release, I will prepare a commit. |
Prior to this fix, builtin_eval would direct output to the io_chain of the job. The problem is with pipes: `builtin_eval` might happily attempt to write unlimited output to the write end of a pipe, but the corresponding reading process has not yet been launched. This results in deadlock. The fix is to buffer all the output from `builtin_eval`. This is not fun but the best that can be done until we have real concurrent processes. Fixes fish-shell#6806
Prior to this fix, builtin_eval would direct output to the io_chain of the job. The problem is with pipes: `builtin_eval` might happily attempt to write unlimited output to the write end of a pipe, but the corresponding reading process has not yet been launched. This results in deadlock. The fix is to buffer all the output from `builtin_eval`. This is not fun but the best that can be done until we have real concurrent processes. cherry-pick of a1f1b9c Fixes #6806
I merged this into 3.1.1 as 5fccfd8 |
I'm having some trouble with the newest change, all "eval" commands here hang up: https://github.com/junegunn/fzf/blob/master/shell/key-bindings.fish Can reproduce it with a simple command like |
Probably the non-buffering behavior can safely be restored for streams that are not redirected: diff --git a/src/builtin_eval.cpp b/src/builtin_eval.cpp
index c9495a669..52b33d2f4 100644
--- a/src/builtin_eval.cpp
+++ b/src/builtin_eval.cpp
@@ -27,22 +27,34 @@ int builtin_eval(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
new_cmd += argv[i];
}
+ shared_ptr<io_bufferfill_t> stdout_fill, stderr_fill;
+ io_chain_t io = *streams.io_chain;
// The output and errput of eval must go to our streams, not to the io_chain in our streams,
- // because they may contain a pipe which is intended to be consumed by a process which is not
- // yet launched (#6806). Make bufferfills to capture it.
- // TODO: we are sloppy and do not honor other redirections; eval'd code won't see for example a
- // redirection of fd 3.
- shared_ptr<io_bufferfill_t> stdout_fill =
- io_bufferfill_t::create(fd_set_t{}, parser.libdata().read_limit, STDOUT_FILENO);
- shared_ptr<io_bufferfill_t> stderr_fill =
- io_bufferfill_t::create(fd_set_t{}, parser.libdata().read_limit, STDERR_FILENO);
- if (!stdout_fill || !stderr_fill) {
- // This can happen if we are unable to create a pipe.
- return STATUS_CMD_ERROR;
+ // because they may contain a pipe which is intended to be consumed by a process which is
+ // not yet launched (#6806). Make bufferfills to capture it.
+ // TODO: we are sloppy and do not honor other redirections; eval'd code won't see for
+ // example a redirection of fd 3.
+ if (streams.out_is_redirected) {
+ stdout_fill =
+ io_bufferfill_t::create(fd_set_t{}, parser.libdata().read_limit, STDOUT_FILENO);
+ if (!stdout_fill) {
+ // This can happen if we are unable to create a pipe.
+ return STATUS_CMD_ERROR;
+ }
+ io.push_back(stdout_fill);
+ }
+ if (streams.err_is_redirected) {
+ stderr_fill =
+ io_bufferfill_t::create(fd_set_t{}, parser.libdata().read_limit, STDERR_FILENO);
+ if (!stderr_fill) {
+ // This can happen if we are unable to create a pipe.
+ return STATUS_CMD_ERROR;
+ }
+ io.push_back(stderr_fill);
}
int status = STATUS_CMD_OK;
- auto res = parser.eval(new_cmd, io_chain_t{stdout_fill, stderr_fill}, streams.parent_pgid);
+ auto res = parser.eval(new_cmd, io, streams.parent_pgid);
if (res.was_empty) {
// Issue #5692, in particular, to catch `eval ""`, `eval "begin; end;"`, etc.
// where we have an argument but nothing is executed.
@@ -54,12 +66,15 @@ int builtin_eval(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
// Finish the bufferfills - exhaust and close our pipes.
// Note it is important that we hold no other references to the bufferfills here - they need to
// deallocate to close.
- std::shared_ptr<io_buffer_t> output = io_bufferfill_t::finish(std::move(stdout_fill));
- std::shared_ptr<io_buffer_t> errput = io_bufferfill_t::finish(std::move(stderr_fill));
+ if (stdout_fill) {
+ std::shared_ptr<io_buffer_t> output = io_bufferfill_t::finish(std::move(stdout_fill));
+ streams.out.append_narrow_buffer(output->buffer());
+ }
- // Copy the output from the bufferfill back to the streams.
- streams.out.append_narrow_buffer(output->buffer());
- streams.err.append_narrow_buffer(errput->buffer());
+ if (stderr_fill) {
+ std::shared_ptr<io_buffer_t> errput = io_bufferfill_t::finish(std::move(stderr_fill));
+ streams.err.append_narrow_buffer(errput->buffer());
+ }
return status;
} |
Commit 5fccfd8, with the fix for #6806, switched eval to buffer its output (like other builtins do). But this prevents using eval with commands that wants to see the tty, especially fzf. So only buffer the output if the output is piped to the next process. This will solve #6955 (which needs to go into a point release).
FYI having upgraded to 3.1.1, my fzf shortcuts now cause the shell to hang. Is this related? Lmk if I can provide any info to make resolving this easier. Thanks. (and thanks for such an awesome shell!) |
@krobelus you were exactly right, I wish I had spotted your review before the 3.1.1 release! #6955 is tracking the regression I introduced. @max-sixty, that's what you're encountering as well. |
Thanks @ridiculousfish & @krobelus ! |
@ridiculousfish Sadly I didn't see it either until after the release when the reports came in. |
Just tested out the latest commit on |
eval "man -k ." | fzf | read
fish version 3.1.0
macos
Used to work fine before 3.1.0
The text was updated successfully, but these errors were encountered: