Thread: fix for readline terminal size problems when window is resized with open pager
fix for readline terminal size problems when window is resized with open pager
From
Merlin Moncure
Date:
Hello, The following patch deals with a long standing gripe of mine that the terminal frequently gets garbled so that when typing. I guess this problem is entirely dependent on pager settings and your interaction patterns with the window (in particular, if you tend to resize the window when the pager is open). Experimenting with the problem, it became pretty clear: libreadline for whatever reason does not get the signal from the kernal telling it that the bounds have changed. This problem does not manifest 100% of the time, you may have to get the pager to open, resize the window, close the pager, and recall a previous long line (or type a new one) several times to get the problem to occur. Nevertheless, the attached seems to end the problem. This adds a dependency to print.c on input.h for the readline macro and the readline header. merlin diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c index 655850b..ede736e 100644 --- a/src/bin/psql/print.c +++ b/src/bin/psql/print.c @@ -27,6 +27,7 @@#include "common.h"#include "mbprint.h"#include "print.h" +#include "input.h" /* * We define the cancel_pressed flag in this file, rather than common.c where @@ -2247,6 +2248,13 @@ ClosePager(FILE *pagerpipe)#ifndef WIN32 pqsignal(SIGPIPE, SIG_DFL);#endif +#ifdef USE_READLINE + /* + * Force libreadline to recheck the terminal size in case pager may + * have handled any terminal resize events. + */ + rl_resize_terminal(); +#endif }}
Re: fix for readline terminal size problems when window is resized with open pager
From
Tom Lane
Date:
Merlin Moncure <mmoncure@gmail.com> writes: > The following patch deals with a long standing gripe of mine that the > terminal frequently gets garbled so that when typing. Hm. I wonder whether rl_resize_terminal() exists in every iteration of libreadline and libedit. regards, tom lane
Re: fix for readline terminal size problems when window is resized with open pager
From
Tom Lane
Date:
I wrote: > Merlin Moncure <mmoncure@gmail.com> writes: >> The following patch deals with a long standing gripe of mine that the >> terminal frequently gets garbled so that when typing. > Hm. I wonder whether rl_resize_terminal() exists in every iteration > of libreadline and libedit. Quick followup: rl_resize_terminal() exists in GNU readline at least as far back as 4.0 (released Feb 1999). However, it doesn't seem to be there at all in libedit; I don't see it in OS X Yosemite's headers, anyway. So we'd need a configure test for this. regards, tom lane
Re: fix for readline terminal size problems when window is resized with open pager
From
Merlin Moncure
Date:
On Tue, Dec 8, 2015 at 2:02 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote: > I wrote: >> Merlin Moncure <mmoncure@gmail.com> writes: >>> The following patch deals with a long standing gripe of mine that the >>> terminal frequently gets garbled so that when typing. > >> Hm. I wonder whether rl_resize_terminal() exists in every iteration >> of libreadline and libedit. > > Quick followup: rl_resize_terminal() exists in GNU readline at least as > far back as 4.0 (released Feb 1999). However, it doesn't seem to be there > at all in libedit; I don't see it in OS X Yosemite's headers, anyway. > So we'd need a configure test for this. All right, I guess this answers the question I was thinking, 'can this be backpatched?' (basically, now). I'll work up a configure test and submit it to the appropriate commit fest. merlin
Re: fix for readline terminal size problems when window is resized with open pager
From
Merlin Moncure
Date:
On Tue, Dec 8, 2015 at 2:33 PM, Merlin Moncure <mmoncure@gmail.com> wrote: > On Tue, Dec 8, 2015 at 2:02 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote: >> I wrote: >>> Merlin Moncure <mmoncure@gmail.com> writes: >>>> The following patch deals with a long standing gripe of mine that the >>>> terminal frequently gets garbled so that when typing. >> >>> Hm. I wonder whether rl_resize_terminal() exists in every iteration >>> of libreadline and libedit. >> >> Quick followup: rl_resize_terminal() exists in GNU readline at least as >> far back as 4.0 (released Feb 1999). However, it doesn't seem to be there >> at all in libedit; I don't see it in OS X Yosemite's headers, anyway. >> So we'd need a configure test for this. > > All right, I guess this answers the question I was thinking, 'can this > be backpatched?' (basically, now). er, meant to say, 'no'. > merlin
Re: fix for readline terminal size problems when window is resized with open pager
From
Merlin Moncure
Date:
On Tue, Dec 8, 2015 at 2:02 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote: > I wrote: >> Merlin Moncure <mmoncure@gmail.com> writes: >>> The following patch deals with a long standing gripe of mine that the >>> terminal frequently gets garbled so that when typing. > >> Hm. I wonder whether rl_resize_terminal() exists in every iteration >> of libreadline and libedit. > > Quick followup: rl_resize_terminal() exists in GNU readline at least as > far back as 4.0 (released Feb 1999). However, it doesn't seem to be there > at all in libedit; I don't see it in OS X Yosemite's headers, anyway. > So we'd need a configure test for this. I thought that maybe raising the signal (SIGWINCH) manually might be a more portable way of doing things but this appears not to work reliably with readline. Poking around the code and reading posts like this (https://www.sourceware.org/ml/gdb-patches/2009-11/msg00597.html) suggests maybe readline's signal handling is too smart for its own good. Oh well. merlin
Re: fix for readline terminal size problems when window is resized with open pager
From
Alvaro Herrera
Date:
Merlin Moncure wrote: > On Tue, Dec 8, 2015 at 2:33 PM, Merlin Moncure <mmoncure@gmail.com> wrote: > > On Tue, Dec 8, 2015 at 2:02 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote: > >> I wrote: > >>> Merlin Moncure <mmoncure@gmail.com> writes: > >>>> The following patch deals with a long standing gripe of mine that the > >>>> terminal frequently gets garbled so that when typing. > >> > >>> Hm. I wonder whether rl_resize_terminal() exists in every iteration > >>> of libreadline and libedit. > >> > >> Quick followup: rl_resize_terminal() exists in GNU readline at least as > >> far back as 4.0 (released Feb 1999). However, it doesn't seem to be there > >> at all in libedit; I don't see it in OS X Yosemite's headers, anyway. > >> So we'd need a configure test for this. > > > > All right, I guess this answers the question I was thinking, 'can this > > be backpatched?' (basically, now). > > er, meant to say, 'no'. Why not? We don't forbid adding configure tests in minor releases, do we? I've been troubled by this many times, so thanks for finding the problem and fixing. -- Álvaro Herrera http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Re: fix for readline terminal size problems when window is resized with open pager
From
Alvaro Herrera
Date:
Tom Lane wrote: > I wrote: > > Merlin Moncure <mmoncure@gmail.com> writes: > >> The following patch deals with a long standing gripe of mine that the > >> terminal frequently gets garbled so that when typing. > > > Hm. I wonder whether rl_resize_terminal() exists in every iteration > > of libreadline and libedit. > > Quick followup: rl_resize_terminal() exists in GNU readline at least as > far back as 4.0 (released Feb 1999). However, it doesn't seem to be there > at all in libedit; I don't see it in OS X Yosemite's headers, anyway. > So we'd need a configure test for this. In libedit (NetBSD's at least) there is el_resize() which seems to do the same thing. -- Álvaro Herrera http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Re: fix for readline terminal size problems when window is resized with open pager
From
Tom Lane
Date:
Alvaro Herrera <alvherre@2ndquadrant.com> writes: > Tom Lane wrote: >> Quick followup: rl_resize_terminal() exists in GNU readline at least as >> far back as 4.0 (released Feb 1999). However, it doesn't seem to be there >> at all in libedit; I don't see it in OS X Yosemite's headers, anyway. >> So we'd need a configure test for this. > In libedit (NetBSD's at least) there is el_resize() which seems to do > the same thing. Hmm. I see this in OS X's histedit.h: void el_resize(EditLine *); but it appears that this is part of a completely separate API with essentially nothing in common with GNU readline. Not sure if we have the motivation to try to support that API in parallel with readline's. I sure don't. regards, tom lane
Re: fix for readline terminal size problems when window is resized with open pager
From
Merlin Moncure
Date:
On Mon, Dec 14, 2015 at 2:50 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote: > Alvaro Herrera <alvherre@2ndquadrant.com> writes: >> Tom Lane wrote: >>> Quick followup: rl_resize_terminal() exists in GNU readline at least as >>> far back as 4.0 (released Feb 1999). However, it doesn't seem to be there >>> at all in libedit; I don't see it in OS X Yosemite's headers, anyway. >>> So we'd need a configure test for this. > >> In libedit (NetBSD's at least) there is el_resize() which seems to do >> the same thing. > > Hmm. I see this in OS X's histedit.h: > > void el_resize(EditLine *); > > but it appears that this is part of a completely separate API with > essentially nothing in common with GNU readline. Not sure if we have > the motivation to try to support that API in parallel with readline's. > I sure don't. This may be moot; some testing demonstrated that libedit was not impacted so it really comes down to having the right readline api call available. Looking at the code ISTM that libedit resets the terminal on every prompt. Also, after some experimentation I had better luck with rl_reset_screen_size() (vs rl_resize_terminal()) that seemed to give more regular behavior with the prompt. So the consolidated patch with the configure check is attached. I'll leave it to the powers that be in terms of how and when to apply this. My gut is that it could probably be patched in now but I'd feel comfortable with more testing then my own perfunctory probing. merlin
Attachment
Re: fix for readline terminal size problems when window is resized with open pager
From
Andreas Karlsson
Date:
On 12/14/2015 01:57 PM, Merlin Moncure wrote: > This may be moot; some testing demonstrated that libedit was not > impacted so it really comes down to having the right readline api call > available. Looking at the code ISTM that libedit resets the terminal > on every prompt. Did you manage to figure out why one was better than the other? The differences between the functions seem rather subtle. rl_reset_screen_size() Does not respect the COLUMNS and ROWS environment variables. _rl_sigwinch_resize_terminal() Internal callback, does the same thing as rl_reset_screen_size() except that it also respects COLUMNS and ROWS. rl_resize_terminal() Respects COLUMNS and ROWS and also has some logic when echo mode is turned on which I have not managed to understand yet. Btw, really nice to see someone working at this. It has bugged me a long time. Andreas
Re: fix for readline terminal size problems when window is resized with open pager
From
Tom Lane
Date:
Andreas Karlsson <andreas@proxel.se> writes: > Did you manage to figure out why one was better than the other? The > differences between the functions seem rather subtle. I'm a bit suspicious of Merlin's recommendation as well. Looking at the readline 6.3 sources, it is rl_resize_terminal() not the other one that is called when an actual SIGWINCH is handled. Another issue is that rl_reset_screen_size() doesn't exist in older copies of readline (I don't see it in 4.0 nor 4.2a, which is what I've got laying around in my archives). So even if we agree that that's the one to use when available, we'd need configure logic to fall back to rl_resize_terminal() otherwise. > rl_resize_terminal() > Respects COLUMNS and ROWS and also has some logic when echo mode is > turned on which I have not managed to understand yet. It looks to me like what it's doing is repainting the current line on the theory that it might be messed up. Since we are, at this point, presumably *not* in the middle of accepting a command line, that should be unnecessary but also harmless. If there is any visible difference in behavior, I should think it would be rl_resize_terminal() that produces more consistent results, because it does have the repaint logic which the other lacks. regards, tom lane
Re: fix for readline terminal size problems when window is resized with open pager
From
Andres Freund
Date:
Hi, First off: Glad that you investigated, this has been bugging me. On 2015-12-14 15:57:22 -0600, Merlin Moncure wrote: > Also, after some experimentation I had better luck with > rl_reset_screen_size() (vs rl_resize_terminal()) that seemed to give > more regular behavior with the prompt. So the consolidated patch with > the configure check is attached. Hm. rl_reset_screen_size() works well for me. rl_resize_terminal() not so much. Apparently the reason for that is that rl_reset_screen_size() doesn't set ignore_env to to true when calling _rl_get_screen_size(). I've verified that just toggling that parameter changes the behaviour. What bugs me about that a bit is that _rl_sigwinch_resize_terminal() sets ignore_env to true. Greetings, Andres Freund
Re: fix for readline terminal size problems when window is resized with open pager
From
Andres Freund
Date:
On 2015-12-16 11:21:53 -0500, Tom Lane wrote: > It looks to me like what it's doing is repainting the current line > on the theory that it might be messed up. Since we are, at this > point, presumably *not* in the middle of accepting a command line, > that should be unnecessary but also harmless. If there is any > visible difference in behavior, I should think it would be > rl_resize_terminal() that produces more consistent results, because > it does have the repaint logic which the other lacks. The repainting actually causes trouble here, if I have \timing enabled. Even without an actual resize even it leads to the Time: line to be displayed in the same line as the query, after the pager was active. Looks like postgres[8444][1]=# SELECT * .. \n ... \nUNION ALLSELECT 1;Time: 2.311 ms So something isn't entirely right after a redraw...
Re: fix for readline terminal size problems when window is resized with open pager
From
Tom Lane
Date:
Andres Freund <andres@anarazel.de> writes: > Hm. rl_reset_screen_size() works well for me. rl_resize_terminal() not > so much. Apparently the reason for that is that rl_reset_screen_size() > doesn't set ignore_env to to true when calling > _rl_get_screen_size(). I've verified that just toggling that parameter > changes the behaviour. [ squint... ] What readline version are you using, and do you have LINES/COLUMNS set in your terminal environment? As far as I can see in the 6.3 sources, the very first call of _rl_get_screen_size will cause LINES/COLUMNS to become set from the results of ioctl(TIOCGWINSZ), assuming that that succeeds, because we do nothing to alter the default values of rl_prefer_env_winsize (0) or rl_change_environment (1). After that, it really doesn't matter whether ignore_env is true or not; this code will track the ioctl as long as rl_prefer_env_winsize stays 0. It may be that the echo stuff is not good, but I'm pretty dubious about ignore_env being the issue. regards, tom lane
Re: fix for readline terminal size problems when window is resized with open pager
From
Andres Freund
Date:
On 2015-12-16 12:02:26 -0500, Tom Lane wrote: > [ squint... ] What readline version are you using, and do you have > LINES/COLUMNS set in your terminal environment? libreadline-dev: Installed: 6.3-8+b4 Both are set - I think bash does that. > It may be that the echo stuff is not good, but I'm pretty dubious > about ignore_env being the issue. Indeed it's not, I'm not entirely sure whether I managed to repeatedly run with the wrong version of psql (doubtful, same terminal), or what strange state I observed. But _rl_get_screen_size (fileno (rl_instream), 0); if (RL_ISSTATE(RL_STATE_REDISPLAYING) == 0) _rl_redisplay_after_sigwinch(); in ClosePager() shows the problem independent of ignore_env or not. I think the difference here is actually that redrawing shows the query after the pager, without it we don't show it again. If you configure less to automatically quit if the query is below one screen (-F) and use \pset pager always the difference is clearly visible: resize (just _rl_get_screen_size()): postgres[12561][1]=# SELECT 1; ┌──────────┐ │ ?column? │ ├──────────┤ │ 1 │ └──────────┘ (1 row) Time: 0.797 ms postgres[12561][1]=# resize & redraw (_rl_get_screen_size() & _rl_redisplay_after_sigwinch): postgres[12393][1]=# SELECT 1; ┌──────────┐ │ ?column? │ ├──────────┤ │ 1 │ └──────────┘ (1 row) postgres[12393][1]=# SELECT 1;Time: 0.555 ms based on that I'm inclined to just go with resize - redisplaying the query after the pager might be desirable, but I think it's an actual behavioural change.
Re: fix for readline terminal size problems when window is resized with open pager
From
Tom Lane
Date:
Andres Freund <andres@anarazel.de> writes: > ... based on that I'm inclined to just go with resize - redisplaying the > query after the pager might be desirable, but I think it's an actual > behavioural change. Hmm ... given that we've not printed "Time:" yet (in \timing mode), I think you're right that we don't want anything printed at this point. It may be that we can't fix this in readline versions that precede the introduction of the resize function. Let me go experiment on my pet dinosaurs. regards, tom lane
Re: fix for readline terminal size problems when window is resized with open pager
From
Andres Freund
Date:
On 2015-12-16 12:23:28 -0500, Tom Lane wrote: > It may be that we can't fix this in readline versions that precede the > introduction of the resize function. Let me go experiment on my pet > dinosaurs. I'm not particularly bothered by not supporting old readline versions here. If we really want to we could basically directly use _rl_get_screen_size() - which seems to have been present from before 4.0. It's not declared static... extern void _rl_get_screen_size (int tty, int ignore_env); and then _rl_get_screen_size (fileno (rl_instream), 0); in ClosePager() seems to do the trick. Andres
Re: fix for readline terminal size problems when window is resized with open pager
From
Tom Lane
Date:
Andres Freund <andres@anarazel.de> writes: > On 2015-12-16 12:23:28 -0500, Tom Lane wrote: >> It may be that we can't fix this in readline versions that precede the >> introduction of the resize function. Let me go experiment on my pet >> dinosaurs. > I'm not particularly bothered by not supporting old readline versions > here. I'm not either, just wanted to know if it was possible. (Answer: no. rl_resize_terminal definitely does not do what we want, neither in current releases nor in 4.2. It looks to me like it's only intended to be called while interactive input is active, which is the only time that libreadline has its signal handler in place.) > If we really want to we could basically directly use > _rl_get_screen_size() - which seems to have been present from before > 4.0. It's not declared static... Nah, I don't think we should rely on calling undocumented internal readline functions. We've lived with this behavior for long enough that I don't think it's a catastrophe if we don't fix it for ancient readline releases. One issue I do have with the patch as proposed is that it will call rl_reset_screen_size even with -n, which does not seem like a good idea. There's no guarantee that rl_reset_screen_size will behave nicely if libreadline hasn't been initialized properly, and even if it does, it will have side-effects on the LINES/COLUMNS environment variables which are potentially user-visible and should not happen with -n. I think the most reasonable way to handle this is to put the call into a new function exported from input.c, where it can be made conditional on useReadline. Except for that minor rearrangement, I think this is a good patch and we should accept it. Does anyone object to back-patching it? regards, tom lane
Re: fix for readline terminal size problems when window is resized with open pager
From
Andres Freund
Date:
On 2015-12-16 13:02:25 -0500, Tom Lane wrote: > > If we really want to we could basically directly use > > _rl_get_screen_size() - which seems to have been present from before > > 4.0. It's not declared static... > > Nah, I don't think we should rely on calling undocumented internal > readline functions. Agreed. > We've lived with this behavior for long enough > that I don't think it's a catastrophe if we don't fix it for ancient > readline releases. Yes. > I think the most reasonable way to handle this is to put the > call into a new function exported from input.c, where it can be > made conditional on useReadline. Sounds good. > Does anyone object to back-patching it? Not here.
Re: fix for readline terminal size problems when window is resized with open pager
From
Merlin Moncure
Date:
On Wed, Dec 16, 2015 at 12:06 PM, Andres Freund <andres@anarazel.de> wrote: > On 2015-12-16 13:02:25 -0500, Tom Lane wrote: >> I think the most reasonable way to handle this is to put the >> call into a new function exported from input.c, where it can be >> made conditional on useReadline. > > Sounds good. I'll right, I'll follow up with that shortly. For posterity, I think you guys arrived at the right conclusion, but the difference between the two public screen reset calls is that one (the original patch) forces a re-display of the prompt and the newer one, rl_reset_screen_size(), does not. With the older patch the best I could come up with was to call rl_crlf() so that the prompt display did not amend to the end of \timing's output. However, that still modified the output relative to what it was pre-patch, which would be impolite to our users in a backpatch scenario. merlin
Re: fix for readline terminal size problems when window is resized with open pager
From
Tom Lane
Date:
I did some more experimentation and concluded that actually, this problem has nothing whatsoever to do with pager invocations. What seems to really be happening is that libreadline activates its SIGWINCH handler only while it's being called to collect input, which is fine in itself, but *it does not notice screen resizes that happen when the handler is not active*. You can prove this by doing, say, "select pg_sleep(10);" and resizing the window before the backend comes back. Readline never notices the resize, even though no pager invocation happens at all. So I now think that print.c shouldn't be involved at all, and the right thing to do is just have gets_interactive() invoke the resize function immediately before calling readline(). That will still leave a window for SIGWINCH to be missed, but it's a pretty tiny one. And somebody oughta report this as a libreadline bug ... regards, tom lane
Re: fix for readline terminal size problems when window is resized with open pager
From
Merlin Moncure
Date:
On Wed, Dec 16, 2015 at 1:29 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote: > I did some more experimentation and concluded that actually, this problem > has nothing whatsoever to do with pager invocations. What seems to really > be happening is that libreadline activates its SIGWINCH handler only while > it's being called to collect input, which is fine in itself, but *it does > not notice screen resizes that happen when the handler is not active*. > > You can prove this by doing, say, "select pg_sleep(10);" and resizing > the window before the backend comes back. Readline never notices the > resize, even though no pager invocation happens at all. > > So I now think that print.c shouldn't be involved at all, and the right > thing to do is just have gets_interactive() invoke the resize function > immediately before calling readline(). That will still leave a window > for SIGWINCH to be missed, but it's a pretty tiny one. right -- agreed. > And somebody oughta report this as a libreadline bug ... See https://bugs.python.org/issue23735 for background. Apparently this is expected behavior (and we are far from the only ones complaining about it): "And so we reach where we are. If a SIGWINCH arrives while readline is not active, and the application using callback mode does not catch it and tell readline about the updated screen dimensions (rl_set_screen_size() exists for this purpose), readline will not know about the new size." merlin
Re: fix for readline terminal size problems when window is resized with open pager
From
Alvaro Herrera
Date:
Tom Lane wrote: > I did some more experimentation and concluded that actually, this problem > has nothing whatsoever to do with pager invocations. What seems to really > be happening is that libreadline activates its SIGWINCH handler only while > it's being called to collect input, which is fine in itself, but *it does > not notice screen resizes that happen when the handler is not active*. I wonder if we're doing the proper things. According to their manual, http://git.savannah.gnu.org/gitweb/?p=readline.git;a=blob_plain;f=doc/readline.html;h=9b7dd842764c81ad496c38a2794361cad964ee90;hb=7628b745a813aac53586b640da056a975f1c443e#SEC44 I think we should be setting rl_catch_signal and/or rl_catch_sigwinch and then perhaps call rl_set_signals(), but I don't think we're doing anything of the sort. -- Álvaro Herrera http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Re: fix for readline terminal size problems when window is resized with open pager
From
Alvaro Herrera
Date:
Alvaro Herrera wrote: > I wonder if we're doing the proper things. According to their manual, > http://git.savannah.gnu.org/gitweb/?p=readline.git;a=blob_plain;f=doc/readline.html;h=9b7dd842764c81ad496c38a2794361cad964ee90;hb=7628b745a813aac53586b640da056a975f1c443e#SEC44 Note: the above link documents readline 6.5 according to git tags. This one is for readline 4.2: http://git.savannah.gnu.org/gitweb/?p=readline.git;a=blob_plain;f=doc/readline.html;hb=abde3125f6228a63e22de708b9edaef62cab0ac3#SEC43 -- Álvaro Herrera http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Re: fix for readline terminal size problems when window is resized with open pager
From
Tom Lane
Date:
Alvaro Herrera <alvherre@2ndquadrant.com> writes: >> I did some more experimentation and concluded that actually, this problem >> has nothing whatsoever to do with pager invocations. What seems to really >> be happening is that libreadline activates its SIGWINCH handler only while >> it's being called to collect input, which is fine in itself, but *it does >> not notice screen resizes that happen when the handler is not active*. > I wonder if we're doing the proper things. According to their manual, > http://git.savannah.gnu.org/gitweb/?p=readline.git;a=blob_plain;f=doc/readline.html;h=9b7dd842764c81ad496c38a2794361cad964ee90;hb=7628b745a813aac53586b640da056a975f1c443e#SEC44 > I think we should be setting rl_catch_signal and/or rl_catch_sigwinch > and then perhaps call rl_set_signals(), but I don't think we're doing > anything of the sort. According to the info page I have here, those are all enabled by default, and we would only need to do something special if we wanted to prevent readline from catching signals. It's possible that 6.3 has made fundamental, incompatible changes in this area and not bothered to update the documentation, but it would be pretty shoddy work on their part. regards, tom lane
Re: fix for readline terminal size problems when window is resized with open pager
From
Tom Lane
Date:
Merlin Moncure <mmoncure@gmail.com> writes: > On Wed, Dec 16, 2015 at 1:29 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote: >> So I now think that print.c shouldn't be involved at all, and the right >> thing to do is just have gets_interactive() invoke the resize function >> immediately before calling readline(). That will still leave a window >> for SIGWINCH to be missed, but it's a pretty tiny one. > right -- agreed. I tried that and found out that the first call dumps core because readline hasn't been initialized yet. To fix that, we need an explicit call to rl_initialize() instead of depending on readline() to do it for us. So I arrive at the attached modified patch. >> And somebody oughta report this as a libreadline bug ... > See https://bugs.python.org/issue23735 for background. Apparently > this is expected behavior (and we are far from the only ones > complaining about it): > "And so we reach where we are. If a SIGWINCH arrives while readline is > not active, and the application using callback mode does not catch it and > tell readline about the updated screen dimensions (rl_set_screen_size() > exists for this purpose), readline will not know about the new size." Meh. At the very least, this is a serious documentation failure on their part, because their docs about interrupt handling look exactly the same as before, to wit saying exactly the opposite of this. regards, tom lane diff --git a/configure b/configure index 8c61390..5772d0e 100755 *** a/configure --- b/configure *************** if test x"$pgac_cv_var_rl_completion_app *** 13232,13238 **** $as_echo "#define HAVE_RL_COMPLETION_APPEND_CHARACTER 1" >>confdefs.h fi ! for ac_func in rl_completion_matches rl_filename_completion_function do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" --- 13232,13238 ---- $as_echo "#define HAVE_RL_COMPLETION_APPEND_CHARACTER 1" >>confdefs.h fi ! for ac_func in rl_completion_matches rl_filename_completion_function rl_reset_screen_size do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/configure.in b/configure.in index b5868b0..44f832f 100644 *** a/configure.in --- b/configure.in *************** LIBS="$LIBS_including_readline" *** 1635,1641 **** if test "$with_readline" = yes; then PGAC_VAR_RL_COMPLETION_APPEND_CHARACTER ! AC_CHECK_FUNCS([rl_completion_matches rl_filename_completion_function]) AC_CHECK_FUNCS([append_history history_truncate_file]) fi --- 1635,1641 ---- if test "$with_readline" = yes; then PGAC_VAR_RL_COMPLETION_APPEND_CHARACTER ! AC_CHECK_FUNCS([rl_completion_matches rl_filename_completion_function rl_reset_screen_size]) AC_CHECK_FUNCS([append_history history_truncate_file]) fi diff --git a/src/bin/psql/input.c b/src/bin/psql/input.c index e377104..c0c5524 100644 *** a/src/bin/psql/input.c --- b/src/bin/psql/input.c *************** gets_interactive(const char *prompt) *** 65,70 **** --- 65,81 ---- { char *result; + /* + * Some versions of readline don't notice SIGWINCH signals that arrive + * when not actively reading input. The simplest fix is to always + * re-read the terminal size. This leaves a window for SIGWINCH to be + * missed between here and where readline() enables libreadline's + * signal handler, but that's probably short enough to be ignored. + */ + #ifdef HAVE_RL_RESET_SCREEN_SIZE + rl_reset_screen_size(); + #endif + /* Enable SIGINT to longjmp to sigint_interrupt_jmp */ sigint_interrupt_enabled = true; *************** initializeInput(int flags) *** 330,335 **** --- 341,347 ---- char home[MAXPGPATH]; useReadline = true; + rl_initialize(); initialize_readline(); useHistory = true; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index a20e0cd..16a272e 100644 *** a/src/include/pg_config.h.in --- b/src/include/pg_config.h.in *************** *** 428,433 **** --- 428,436 ---- /* Define to 1 if you have the `rl_filename_completion_function' function. */ #undef HAVE_RL_FILENAME_COMPLETION_FUNCTION + /* Define to 1 if you have the `rl_reset_screen_size' function. */ + #undef HAVE_RL_RESET_SCREEN_SIZE + /* Define to 1 if you have the <security/pam_appl.h> header file. */ #undef HAVE_SECURITY_PAM_APPL_H
Re: fix for readline terminal size problems when window is resized with open pager
From
Tom Lane
Date:
I wrote: > Merlin Moncure <mmoncure@gmail.com> writes: >> See https://bugs.python.org/issue23735 for background. Apparently >> this is expected behavior (and we are far from the only ones >> complaining about it): >> "And so we reach where we are. If a SIGWINCH arrives while readline is >> not active, and the application using callback mode does not catch it and >> tell readline about the updated screen dimensions (rl_set_screen_size() >> exists for this purpose), readline will not know about the new size." > Meh. At the very least, this is a serious documentation failure on their > part, because their docs about interrupt handling look exactly the same > as before, to wit saying exactly the opposite of this. Hm ... actually, the claim that this is somehow new behavior in libreadline 6.3 or thereabouts is purest bilge, because 4.2a (released Nov 2001) acts exactly the same. regards, tom lane
Re: fix for readline terminal size problems when window is resized with open pager
From
Merlin Moncure
Date:
On Wed, Dec 16, 2015 at 2:12 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote: > Merlin Moncure <mmoncure@gmail.com> writes: >> On Wed, Dec 16, 2015 at 1:29 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote: >>> So I now think that print.c shouldn't be involved at all, and the right >>> thing to do is just have gets_interactive() invoke the resize function >>> immediately before calling readline(). That will still leave a window >>> for SIGWINCH to be missed, but it's a pretty tiny one. > >> right -- agreed. > > I tried that and found out that the first call dumps core because readline > hasn't been initialized yet. To fix that, we need an explicit call to > rl_initialize() instead of depending on readline() to do it for us. > So I arrive at the attached modified patch. This is working great. Is there anything left for me to do here? merlin
Re: fix for readline terminal size problems when window is resized with open pager
From
Tom Lane
Date:
Merlin Moncure <mmoncure@gmail.com> writes: > This is working great. Is there anything left for me to do here? Nope, it's committed. regards, tom lane