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: Rin Okuyama
Subject: Re: [Bug-readline] [PATCH] Gnuplot on macOS does not suspend by Control-z
Date: Wed, 22 Nov 2017 19:07:49 +0900
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:52.0) Gecko/20100101 Thunderbird/52.4.0

Thank you for your kind reply!

Does GNUplot install a handler for SIGTSTP or ignore it? The behavior
you describe, in the absence of any other changes, sounds like something
sets the DSUSP character to ^Z.

No, it does not install any signal handlers.

It must be something specific to GNUplot, since the simple readline test
programs handle ^Z as expected when run on MacOS.

I examined differences between the sample programs and gnuplot, then
I found that gnuplot specifies its own wrapper for getc(3) to
rl_getc_function:

----
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);
                        ...
                } while (!FD_ISSET(fd, &fds));
        }
        return getc(fp);
}
----
(This is a simplified version. Please refer to getc_wrapper() in
src/plot.c and X11_waitforinput() in term/x11.trm for more details.)

The reasons why gnuplot does not suspend by Control-z, and does by
any key following Control-z are,

(1) when external_fd >= 0, select(2) cannot catch SIGTSTP, and
(2) when external_fd < 0, getc(3) cannot catch SIGTSTP

Therefore I modified the code as below:

----
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);
#ifdef HAVE_LIBREADLINE
                        extern int _rl_caught_signal;
                        void _rl_signal_handler(int);
                        if (_rl_caught_signal)
                                _rl_signal_handler(_rl_caught_signal);
#endif
                        ierr = select(external_fd + 1, &fds, 0, 0, NULL);
                        ...
                } while (!FD_ISSET(fd, &fds));
        }
#ifdef HAVE_LIBREADLINE
        int rl_getc(FILE*);
        return rl_getc(fp);
#else
        return getc(fp);
#endif
}
----

Then, it successfully suspends regardless of external_fd.

However, as you can see, this is a kind of dirty hack. I wonder whether
there are some portable ways to do like this? I guess that rl_getc() in
the second ifdef block can be replaced by something like this:

----
int (*readline_getc)(FILE*) = NULL;
...
readline_getc = rl_getc_function;
rl_getc_function = getc_wrapper;
...
int gnuplot_getc(FILE *fp) {
        if (readline_getc)
                return readline_getc(fp);
        else
                return getc(fp);
}
----

But, how about the first ifdef block?

Best regards,
Rin Okuyama

On 2017/11/22 4:36, Chet Ramey wrote:
On 11/21/17 7:53 AM, Rin Okuyama wrote:
Hi,

Gnuplot on macOS does not suspend by Control-z in its command line.
Please find the details below and attached patch.

Does GNUplot install a handler for SIGTSTP or ignore it? The behavior
you describe, in the absence of any other changes, sounds like something
sets the DSUSP character to ^Z.

At the moment, readline does not disable VSUSP, and expect SIGTSTP to
be appropriately sent by the tty driver. However, unfortunately, it
does not work on macOS.

It must be something specific to GNUplot, since the simple readline test
programs handle ^Z as expected when run on MacOS.





reply via email to

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