diff mbox

[BUG] Here-document redirection with vi/emacs on

Message ID d343eac0-b110-609b-6f7e-aa85e29f9091@gigawatt.nl (mailing list archive)
State Accepted
Delegated to: Herbert Xu
Headers show

Commit Message

Harald van Dijk June 29, 2017, 11:33 p.m. UTC
On 27/06/17 16:29, Zando Fardones wrote:
> Hello,
> 
> I think I've found a bug when using the here-document redirection in
> an interactive shell. What basically happens is that you can't see the
> command output if you set the "vi" or "emacs" options.

That's not quite what happens: the here-document contents got lost, so 
there is no command output to see. Nice find.

The problem is that getprompt() is implicitly called by el_gets(). This 
messes with the memory used by the parser to store the here-document's 
contents. In the non-emacs/vi case, the prompt is explicitly written by 
setprompt(), which wraps the getprompt() call in a 
pushstackmark()/popstackmark() pair to restore the state so that parsing 
can continue. But when getprompt() is called by el_gets(), it knows 
nothing about this.

The whole call to el_gets() can be surrounded by another 
pushstackmark()/popstackmark() pair to solve the problem, as attached.

Cheers,
Harald van Dijk

Comments

Herbert Xu March 10, 2018, 8:03 a.m. UTC | #1
On Fri, Jun 30, 2017 at 01:33:29AM +0200, Harald van Dijk wrote:
> On 27/06/17 16:29, Zando Fardones wrote:
> > Hello,
> > 
> > I think I've found a bug when using the here-document redirection in
> > an interactive shell. What basically happens is that you can't see the
> > command output if you set the "vi" or "emacs" options.
> 
> That's not quite what happens: the here-document contents got lost, so 
> there is no command output to see. Nice find.
> 
> The problem is that getprompt() is implicitly called by el_gets(). This 
> messes with the memory used by the parser to store the here-document's 
> contents. In the non-emacs/vi case, the prompt is explicitly written by 
> setprompt(), which wraps the getprompt() call in a 
> pushstackmark()/popstackmark() pair to restore the state so that parsing 
> can continue. But when getprompt() is called by el_gets(), it knows 
> nothing about this.
> 
> The whole call to el_gets() can be surrounded by another 
> pushstackmark()/popstackmark() pair to solve the problem, as attached.

Patch applied.  Thanks.
diff mbox

Patch

--- a/src/input.c
+++ b/src/input.c
@@ -147,8 +147,12 @@  retry:
 		static const char *rl_cp;
 		static int el_len;
 
-		if (rl_cp == NULL)
+		if (rl_cp == NULL) {
+			struct stackmark smark;
+			pushstackmark(&smark, stackblocksize());
 			rl_cp = el_gets(el, &el_len);
+			popstackmark(&smark);
+		}
 		if (rl_cp == NULL)
 			nr = 0;
 		else {