]> git.eshelyaron.com Git - emacs.git/commit
Fix reference-counting of Eshell I/O handles
authorJim Porter <jporterbugs@gmail.com>
Sat, 24 Dec 2022 22:31:50 +0000 (14:31 -0800)
committerJim Porter <jporterbugs@gmail.com>
Fri, 30 Dec 2022 06:38:25 +0000 (22:38 -0800)
commit073da412a139e317959f56e359ed12de726a0a35
treecca61c46ca20b11b58501883bcb60737d6eecbd7
parent89e7bb230d643b3619d7e2ed6855c35184032542
Fix reference-counting of Eshell I/O handles

This ensures that output targets in Eshell are only closed when Eshell
is actually done with them.  In particular, this means that
"{ echo foo; echo bar } | rev" prints "raboof" as expected
(bug#59545).

* lisp/eshell/esh-io.el (eshell-create-handles): Structure the handles
differently so the targets and their ref-count can be shared.
(eshell-duplicate-handles): Reimplement this to share targets between
the original and new handle sets.  Add STEAL-P argument.
(eshell-protect-handles, eshell-copy-output-handle)
(eshell-interactive-output-p, eshell-output-object): Account for
changes to the handle structure.
(eshell-close-handle): New function...
(eshell-close-handles, eshell-set-output-handle): ... use it.
(eshell-get-targets): Remove.  This only existed to make the previous
implementation of 'eshell-duplicate-handles' work.

* lisp/eshell/esh-cmd.el (eshell-with-copied-handles): New argument
STEAL-P.
(eshell-do-pipelines): Use STEAL-P for the last item in the pipeline.
(eshell-parse-command): Don't copy handles for the last command in the
list; explain why we can't use STEAL-P here.
(eshell-eval-command): When queuing input, set 'eshell-command-body'
and 'eshell-test-body' for the 'if' conditional (see
'eshell-do-eval').

* test/lisp/eshell/esh-io-tests.el (esh-io-test/redirect-pipe): Split
into...
(esh-io-test/pipeline/default, esh-io-test/pipeline/all): ... these.
(esh-io-test/pipeline/subcommands): New test.

* test/lisp/eshell/esh-cmd-tests.el (esh-cmd-test/for-loop-pipe)
(esh-cmd-test/while-loop-pipe, esh-cmd-test/if-statement-pipe)
esh-cmd-test/if-else-statement-pipe): New tests.
(esh-cmd-test/while-loop): Use 'pop' to simplify the test a bit.

* test/lisp/eshell/eshell-test-helpers.el
(eshell-test--max-subprocess-time): Rename to...
(eshell-test--max-wait-time): ... this.
(eshell-wait-for): New function...
(eshell-wait-for-subprocess): ... use it.

* test/lisp/eshell/eshell-tests.el (eshell-test/queue-input): Fix this
test.  Previously, it didn't correctly verify that the original
command completed.

* test/lisp/eshell/em-tramp-tests.el
(em-tramp-test/should-replace-command): New macro...
(em-tramp-test/su-default, em-tramp-test/su-user)
(em-tramp-test/su-login, em-tramp-test/sudo-shell)
(em-tramp-test/sudo-user-shell, em-tramp-test/doas-shell)
(em-tramp-test/doas-user-shell): ... use it.
lisp/eshell/esh-cmd.el
lisp/eshell/esh-io.el
test/lisp/eshell/em-tramp-tests.el
test/lisp/eshell/esh-cmd-tests.el
test/lisp/eshell/esh-io-tests.el
test/lisp/eshell/eshell-tests-helpers.el
test/lisp/eshell/eshell-tests.el