bug-readline
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Bug-readline] [PATCH] Gnuplot on macOS does not suspend by Control-


From: Chet Ramey
Subject: Re: [Bug-readline] [PATCH] Gnuplot on macOS does not suspend by Control-z
Date: Fri, 24 Nov 2017 10:27:10 -0500
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:52.0) Gecko/20100101 Thunderbird/52.4.0

On 11/23/17 10:52 AM, Rin Okuyama wrote:
> On 2017/11/23 11:27, Chet Ramey wrote:
>> Yes, it can.  If you act when select() returns -1/EINTR, check for a
>> caught signal, and break out of the loop, it should do what you want.
>> (I'm not sure why you put the signal check before the call to select().)
>> The reason it will work is that the first thing rl_getc does is to check
>> for and handle any caught signals, so you can be sure that calling it
>> when you've detected a signal will cause the signal handler to be invoked.
>> It's just adding a dependency on a particular implementation.
>>
>> I'm not sure there's a compelling reason to expose readline's internal
>> signal handling to applications. If you really need it, there are a
>> couple of workarounds, both covered here.
> 
> Thank you for your comment. As you pointed out, the signal check
> should be within the select(2) loop. New versions would be
> 
> (1) _rl_signal_handler() is used as before:
> 
> ----
> int getc_wrapper(FILE *fp) {
>     fd_set fds;
>     int fd = fileno(fp);
>     int ierr;
>     if (external_fd >= 0) {
>         do {
>             FD_ZERO(&fds);
>             FD_SET(fd, &fds);
>             FD_SET(external_fd, &fds);
>             ierr = select(external_fd + 1, &fds, 0, 0, NULL);
>             if (ierr < 0 && errno == EINTR) {
> #ifdef HAVE_LIBREADLINE
>                 if (_rl_caught_signal)
>                     _rl_signal_handler(_rl_caught_signal);
> #endif
>                 continue;
>             }
> 
> ... poll and read from external_fd ...
> 
>         } while (!FD_ISSET(fd, &fds));
>     }
> #ifdef HAVE_LIBREADLINE
>     return rl_getc(fp);
> #else
>     return getc(fp);
> #endif
> }
> ----
> 
> (2) the 1st ifdef block is simply replaced by
> 
> ----
> #ifdef HAVE_LIBREADLINE
>                 return rl_getc(fp);
> #endif
> ----
> 
> Both (1) and (2) suspend by Control-z. However, variant (2) does not
> accept input from external_fd (it is actually mouse driver) after
> continue from suspend, unless the first any input arrives from tty.
> I guess that this is inevitable with rl_getc(). How do you think?

This isn't what I said. You only want to call rl_getc in that scenario
unless you're sure that the select() was interrupted by a signal, because
what you're interested in is the side effect of its signal handling.

You can either break out of the loop, in which case the call to rl_getc
following the loop will (as a side effect) handle the signal, or you
can call it explicitly. If you call it in the loop, you only want to
call it if you're sure you have a signal handler call pending to avoid
the case you encountered.  So something like (readline-7.0):

if (ierr < 0 && errno == EINTR)
 if (rl_pending_signal ()) return rl_getc ();

In either case, readline or not, it's probably a good idea to analyze
the signal handling behavior so if you choose to continue to the loop
when select returns an error you won't somehow get into an infinite loop.


-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    address@hidden    http://cnswww.cns.cwru.edu/~chet/



reply via email to

[Prev in Thread] Current Thread [Next in Thread]