diff options
| author | Paul Eggert | 2017-02-01 15:18:44 -0800 |
|---|---|---|
| committer | Paul Eggert | 2017-02-01 15:23:19 -0800 |
| commit | b01ac672be1277833964d2d53f6dd26560c70343 (patch) | |
| tree | 31b886a5084f20135bec50fe831dcfeed229c619 /src/keyboard.c | |
| parent | 33be50037c2b4cdb002538534e9915c6bad253b7 (diff) | |
| download | emacs-b01ac672be1277833964d2d53f6dd26560c70343.tar.gz emacs-b01ac672be1277833964d2d53f6dd26560c70343.zip | |
Revamp quitting and fix infloops
This fixes some infinite loops that cannot be quitted out of,
e.g., (defun foo () (nth most-positive-fixnum '#1=(1 . #1#)))
when byte-compiled and when run under X. See:
http://lists.gnu.org/archive/html/emacs-devel/2017-01/msg00577.html
This also attempts to keep the performance improvements I recently
added, as much as possible under the constraint that the infloops
must be caught. In some cases this fixes infloop bugs recently
introduced when I removed immediate_quit.
* src/alloc.c (Fmake_list):
Use rarely_quit, not maybe_quit, for speed in the usual case.
* src/bytecode.c (exec_byte_code):
* src/editfns.c (Fcompare_buffer_substrings):
* src/fns.c (Fnthcdr):
* src/syntax.c (scan_words, skip_chars, skip_syntaxes)
(Fbackward_prefix_chars):
Use rarely_quit so that users can C-g out of long loops.
* src/callproc.c (call_process_cleanup, call_process):
* src/fileio.c (read_non_regular, Finsert_file_contents):
* src/indent.c (compute_motion):
* src/syntax.c (scan_words, Fforward_comment):
Remove now-unnecessary maybe_quit calls.
* src/callproc.c (call_process):
* src/doc.c (get_doc_string, Fsnarf_documentation):
* src/fileio.c (Fcopy_file, read_non_regular, Finsert_file_contents):
* src/lread.c (safe_to_load_version):
* src/sysdep.c (system_process_attributes) [GNU_LINUX]:
Use emacs_read_quit instead of emacs_read in places where
C-g handling is safe.
* src/eval.c (maybe_quit): Move comment here from lisp.h.
* src/fileio.c (Fcopy_file, e_write):
Use emacs_write_quit instead of emacs_write_sig in places where
C-g handling is safe.
* src/filelock.c (create_lock_file): Use emacs_write, not
plain write, as emacs_write no longer has a problem.
(read_lock_data): Use emacs_read, not read, as emacs_read
no longer has a problem.
* src/fns.c (rarely_quit): Move to lisp.h and rename to
incr_rarely_quit. All uses changed..
* src/fns.c (Fmemq, Fmemql, Fassq, Frassq, Fplist_put, Fplist_member):
* src/indent.c (compute_motion):
* src/syntax.c (find_defun_start, back_comment, forw_comment)
(Fforward_comment, scan_lists, scan_sexps_forward):
Use incr_rarely_quit so that users can C-g out of long loops.
* src/fns.c (Fnconc): Move incr_rarely_quit call to within
inner loop, so that it catches C-g there too.
* src/keyboard.c (tty_read_avail_input): Remove commented-out
and now-obsolete code dealing with interrupts.
* src/lisp.h (rarely_quit, incr_rarely_quit): New functions,
the latter moved here from fns.c and renamed from rarely_quit.
(emacs_read_quit, emacs_write_quit): New decls.
* src/search.c (find_newline, search_buffer, find_newline1):
Add maybe_quit to catch C-g.
* src/sysdep.c (get_child_status): Always invoke maybe_quit
if interruptible, so that the caller need not bother.
(emacs_nointr_read, emacs_read_quit, emacs_write_quit):
New functions.
(emacs_read): Rewrite in terms of emacs_nointr_read.
Do not handle C-g or signals; that is now for emacs_read_quit.
(emacs_full_write): Replace PROCESS_SIGNALS two-way arg
with INTERRUPTIBLE three-way arg. All uses changed.
Diffstat (limited to 'src/keyboard.c')
| -rw-r--r-- | src/keyboard.c | 48 |
1 files changed, 15 insertions, 33 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index 317669d6a1a..a86e7c5f8e4 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -7041,40 +7041,22 @@ tty_read_avail_input (struct terminal *terminal, | |||
| 7041 | 7041 | ||
| 7042 | /* Now read; for one reason or another, this will not block. | 7042 | /* Now read; for one reason or another, this will not block. |
| 7043 | NREAD is set to the number of chars read. */ | 7043 | NREAD is set to the number of chars read. */ |
| 7044 | do | 7044 | nread = emacs_read (fileno (tty->input), (char *) cbuf, n_to_read); |
| 7045 | { | 7045 | /* POSIX infers that processes which are not in the session leader's |
| 7046 | nread = emacs_read (fileno (tty->input), (char *) cbuf, n_to_read); | 7046 | process group won't get SIGHUPs at logout time. BSDI adheres to |
| 7047 | /* POSIX infers that processes which are not in the session leader's | 7047 | this part standard and returns -1 from read (0) with errno==EIO |
| 7048 | process group won't get SIGHUPs at logout time. BSDI adheres to | 7048 | when the control tty is taken away. |
| 7049 | this part standard and returns -1 from read (0) with errno==EIO | 7049 | Jeffrey Honig <jch@bsdi.com> says this is generally safe. */ |
| 7050 | when the control tty is taken away. | 7050 | if (nread == -1 && errno == EIO) |
| 7051 | Jeffrey Honig <jch@bsdi.com> says this is generally safe. */ | 7051 | return -2; /* Close this terminal. */ |
| 7052 | if (nread == -1 && errno == EIO) | 7052 | #if defined AIX && defined _BSD |
| 7053 | return -2; /* Close this terminal. */ | 7053 | /* The kernel sometimes fails to deliver SIGHUP for ptys. |
| 7054 | #if defined (AIX) && defined (_BSD) | 7054 | This looks incorrect, but it isn't, because _BSD causes |
| 7055 | /* The kernel sometimes fails to deliver SIGHUP for ptys. | 7055 | O_NDELAY to be defined in fcntl.h as O_NONBLOCK, |
| 7056 | This looks incorrect, but it isn't, because _BSD causes | 7056 | and that causes a value other than 0 when there is no input. */ |
| 7057 | O_NDELAY to be defined in fcntl.h as O_NONBLOCK, | 7057 | if (nread == 0) |
| 7058 | and that causes a value other than 0 when there is no input. */ | 7058 | return -2; /* Close this terminal. */ |
| 7059 | if (nread == 0) | ||
| 7060 | return -2; /* Close this terminal. */ | ||
| 7061 | #endif | ||
| 7062 | } | ||
| 7063 | while ( | ||
| 7064 | /* We used to retry the read if it was interrupted. | ||
| 7065 | But this does the wrong thing when O_NONBLOCK causes | ||
| 7066 | an EAGAIN error. Does anybody know of a situation | ||
| 7067 | where a retry is actually needed? */ | ||
| 7068 | #if 0 | ||
| 7069 | nread < 0 && (errno == EAGAIN || errno == EFAULT | ||
| 7070 | #ifdef EBADSLT | ||
| 7071 | || errno == EBADSLT | ||
| 7072 | #endif | ||
| 7073 | ) | ||
| 7074 | #else | ||
| 7075 | 0 | ||
| 7076 | #endif | 7059 | #endif |
| 7077 | ); | ||
| 7078 | 7060 | ||
| 7079 | #ifndef USABLE_FIONREAD | 7061 | #ifndef USABLE_FIONREAD |
| 7080 | #if defined (USG) || defined (CYGWIN) | 7062 | #if defined (USG) || defined (CYGWIN) |