-
-
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
Hangs with no output when called from Emacs with make-process and pipe connection type #951
Comments
Sorry, but this bug report isn't something I can understand. Please reproduce the problem outside emacs. Another problem with this bug report is that I have no idea what it is you are trying to do. Another problem is that you say that grep works, but you actually seem to be invoking something else, namely, The typical root cause of this sort of behavior is that ripgrep is blocking on stdin because it thinks you want to search stdin. Namely, when no paths are given to ripgrep, then it must guess at what you want. If it looks like there is something on stdin, then it will search stdin. Otherwise, it searches the current working directory. Often, the simplest work around is too just be explicit. e.g., ag should not be used as a model of correctness. It has so many bugs that it sometimes only does the "right" thing accidentally. With that said, it would be interesting to compare the stdin checking code in both tools, but I'm in mobile. |
Hi,
Thanks, you're right that the problem was that the directory to search was unspecified. This works: (let ((default-directory "~/src/emacs/emacs"))
(setq argh (make-process :name "rg"
:command (list "rg" "TODO" ".") ; <- "." specified the current directory
:connection-type 'pipe ; <- using a pipe instead of a pty
:buffer (get-buffer-create "*rg*"))))
(with-current-buffer (process-buffer argh)
(length (buffer-string))) ;; => 210825
(process-status argh) ;; => exit
This is difficult (for me, at least) because the problem seems to be at a deeper level than, e.g. calling
Yes, it seems that, basically, when However, Maybe this is the intended behavior, that when rg --help
...
rg [OPTIONS] PATTERN [PATH ...]
rg [OPTIONS] [-e PATTERN ...] [-f FILE ...] [PATH ...]
rg [OPTIONS] --files [PATH ...]
rg [OPTIONS] --type-list The only mention of STDIN is:
So I guess that either this needs to be documented clearly, or the behavior needs to be improved to search for files unless data is received on STDIN. For parity with
Indeed, I looked at
$ cat /usr/bin/rgrep
#!/bin/sh
exec grep -r "$@" Thanks for your help. |
See <BurntSushi/ripgrep#951>. Thanks to @BurntSushi for his help.
The fact that
Thus, there is no such thing as "parity" in this case. This is one of the fundamental differences between ripgrep and grep. Note that I still don't know what it is you're trying to achieve. Why are you connecting a pipe to your process when you don't want to send anything on stdin?
When no file paths are given to ripgrep, it uses a heuristic to decide what to do. Namely, ripgrep will block to search on stdin when no paths are given and stdin is not a tty and stdin is either a file or a fifo. In all other cases, it searches the current working directory. When you connect a pipe to it, my guess is that ripgrep probably sees that as a fifo and blocks.
The only difference that I can see between ag and ripgrep on this particular issue is that ripgrep checks if stdin is a tty or not. If it's a tty, then it always does recursive search. The corollary to that is that the only way for ripgrep to search stdin is if its stdin is not a tty. ag has no such check. All it does is check if stdin is a file or a fifo (which ripgrep also does): rv = fstat(fileno(stdin), &statbuf);
if (rv == 0) {
if (S_ISFIFO(statbuf.st_mode) || S_ISREG(statbuf.st_mode)) {
opts.search_stream = 1;
}
} That ag doesn't block is actually interesting, because in order for ripgrep to search stdin, it must detect stdin as either a file or a fifo. That should cause ag to also attempt to search stdin. So probably something else is going on, but diving into emacs is beyond the scope of what I'm willing to debug.
It might be worth a mention in the docs, but ripgrep's default behavior is pretty much what you'd expect it to do. If you don't give it a path, then it searches CWD, unless you're piping something into it, in which case, it searches that data instead. |
Thanks, I understand better now. I think it was actually an accident that I originally ran
Because Emacs' process code works much better when it uses a pipe rather than emulating a tty. Chris Wellons explains the details in his blog: http://nullprogram.com/blog/2018/01/17/ It's very interesting how he used DTrace to figure out what was going on between
In this case, the problem was indeed that I misunderstood
That at least shows that connecting a pipe to Thanks. |
@alphapapa I like that doc suggestion, yes! |
See <BurntSushi/ripgrep#951>. Thanks to @BurntSushi for his help.
See <BurntSushi/ripgrep#951>. Thanks to @BurntSushi for his help.
I am not sure but cosmicexplorer/helm-rg#29 might be related since it involves emacs hanging when calling rg. TBH I didn't really understand the resolution here but posting the link in case some future reader finds it helpful. |
So, after the jump to ripgrep 13, also neovim's
This is also very well documented in the manpage/documentation of ripgrep:
In most cases it should be therefore sufficient to add a This has also been suggested at vi.stackexchange.com |
Aye. See also: #1892 |
What version of ripgrep are you using?
ripgrep 0.8.1 (rev c8e9f25)
-SIMD -AVX
How did you install ripgrep?
Debian package downloaded from link in readme.
What operating system are you using ripgrep on?
Ubuntu 14.04
Emacs 26.1
Describe your question, feature request, or bug.
rg
does not seem to work properly with regard to pipes.grep
works:rg
does not:The process is still running:
However, if I use the
pty
type, it works:ag
also seems to work correctly, likegrep
.Thanks for your help.
The text was updated successfully, but these errors were encountered: