aboutsummaryrefslogtreecommitdiffstats
path: root/src/fileio.c
diff options
context:
space:
mode:
authorPaul Eggert2017-02-01 15:18:44 -0800
committerPaul Eggert2017-02-01 15:23:19 -0800
commitb01ac672be1277833964d2d53f6dd26560c70343 (patch)
tree31b886a5084f20135bec50fe831dcfeed229c619 /src/fileio.c
parent33be50037c2b4cdb002538534e9915c6bad253b7 (diff)
downloademacs-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/fileio.c')
-rw-r--r--src/fileio.c55
1 files changed, 23 insertions, 32 deletions
diff --git a/src/fileio.c b/src/fileio.c
index a109737240f..38400623793 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2030,9 +2030,9 @@ permissions. */)
2030 { 2030 {
2031 char buf[MAX_ALLOCA]; 2031 char buf[MAX_ALLOCA];
2032 ptrdiff_t n; 2032 ptrdiff_t n;
2033 for (newsize = 0; 0 < (n = emacs_read (ifd, buf, sizeof buf)); 2033 for (newsize = 0; 0 < (n = emacs_read_quit (ifd, buf, sizeof buf));
2034 newsize += n) 2034 newsize += n)
2035 if (emacs_write_sig (ofd, buf, n) != n) 2035 if (emacs_write_quit (ofd, buf, n) != n)
2036 report_file_error ("Write error", newname); 2036 report_file_error ("Write error", newname);
2037 if (n < 0) 2037 if (n < 0)
2038 report_file_error ("Read error", file); 2038 report_file_error ("Read error", file);
@@ -3396,13 +3396,10 @@ decide_coding_unwind (Lisp_Object unwind_data)
3396static Lisp_Object 3396static Lisp_Object
3397read_non_regular (Lisp_Object state) 3397read_non_regular (Lisp_Object state)
3398{ 3398{
3399 int nbytes; 3399 int nbytes = emacs_read_quit (XSAVE_INTEGER (state, 0),
3400 3400 ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE
3401 maybe_quit (); 3401 + XSAVE_INTEGER (state, 1)),
3402 nbytes = emacs_read (XSAVE_INTEGER (state, 0), 3402 XSAVE_INTEGER (state, 2));
3403 ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE
3404 + XSAVE_INTEGER (state, 1)),
3405 XSAVE_INTEGER (state, 2));
3406 /* Fast recycle this object for the likely next call. */ 3403 /* Fast recycle this object for the likely next call. */
3407 free_misc (state); 3404 free_misc (state);
3408 return make_number (nbytes); 3405 return make_number (nbytes);
@@ -3746,17 +3743,17 @@ by calling `format-decode', which see. */)
3746 int nread; 3743 int nread;
3747 3744
3748 if (st.st_size <= (1024 * 4)) 3745 if (st.st_size <= (1024 * 4))
3749 nread = emacs_read (fd, read_buf, 1024 * 4); 3746 nread = emacs_read_quit (fd, read_buf, 1024 * 4);
3750 else 3747 else
3751 { 3748 {
3752 nread = emacs_read (fd, read_buf, 1024); 3749 nread = emacs_read_quit (fd, read_buf, 1024);
3753 if (nread == 1024) 3750 if (nread == 1024)
3754 { 3751 {
3755 int ntail; 3752 int ntail;
3756 if (lseek (fd, - (1024 * 3), SEEK_END) < 0) 3753 if (lseek (fd, - (1024 * 3), SEEK_END) < 0)
3757 report_file_error ("Setting file position", 3754 report_file_error ("Setting file position",
3758 orig_filename); 3755 orig_filename);
3759 ntail = emacs_read (fd, read_buf + nread, 1024 * 3); 3756 ntail = emacs_read_quit (fd, read_buf + nread, 1024 * 3);
3760 nread = ntail < 0 ? ntail : nread + ntail; 3757 nread = ntail < 0 ? ntail : nread + ntail;
3761 } 3758 }
3762 } 3759 }
@@ -3861,14 +3858,11 @@ by calling `format-decode', which see. */)
3861 report_file_error ("Setting file position", orig_filename); 3858 report_file_error ("Setting file position", orig_filename);
3862 } 3859 }
3863 3860
3864 maybe_quit ();
3865 /* Count how many chars at the start of the file 3861 /* Count how many chars at the start of the file
3866 match the text at the beginning of the buffer. */ 3862 match the text at the beginning of the buffer. */
3867 while (1) 3863 while (true)
3868 { 3864 {
3869 int nread, bufpos; 3865 int nread = emacs_read_quit (fd, read_buf, sizeof read_buf);
3870
3871 nread = emacs_read (fd, read_buf, sizeof read_buf);
3872 if (nread < 0) 3866 if (nread < 0)
3873 report_file_error ("Read error", orig_filename); 3867 report_file_error ("Read error", orig_filename);
3874 else if (nread == 0) 3868 else if (nread == 0)
@@ -3890,7 +3884,7 @@ by calling `format-decode', which see. */)
3890 break; 3884 break;
3891 } 3885 }
3892 3886
3893 bufpos = 0; 3887 int bufpos = 0;
3894 while (bufpos < nread && same_at_start < ZV_BYTE 3888 while (bufpos < nread && same_at_start < ZV_BYTE
3895 && FETCH_BYTE (same_at_start) == read_buf[bufpos]) 3889 && FETCH_BYTE (same_at_start) == read_buf[bufpos])
3896 same_at_start++, bufpos++; 3890 same_at_start++, bufpos++;
@@ -3910,7 +3904,7 @@ by calling `format-decode', which see. */)
3910 del_range_1 (same_at_start, same_at_end, 0, 0); 3904 del_range_1 (same_at_start, same_at_end, 0, 0);
3911 goto handled; 3905 goto handled;
3912 } 3906 }
3913 maybe_quit (); 3907
3914 /* Count how many chars at the end of the file 3908 /* Count how many chars at the end of the file
3915 match the text at the end of the buffer. But, if we have 3909 match the text at the end of the buffer. But, if we have
3916 already found that decoding is necessary, don't waste time. */ 3910 already found that decoding is necessary, don't waste time. */
@@ -3932,7 +3926,8 @@ by calling `format-decode', which see. */)
3932 total_read = nread = 0; 3926 total_read = nread = 0;
3933 while (total_read < trial) 3927 while (total_read < trial)
3934 { 3928 {
3935 nread = emacs_read (fd, read_buf + total_read, trial - total_read); 3929 nread = emacs_read_quit (fd, read_buf + total_read,
3930 trial - total_read);
3936 if (nread < 0) 3931 if (nread < 0)
3937 report_file_error ("Read error", orig_filename); 3932 report_file_error ("Read error", orig_filename);
3938 else if (nread == 0) 3933 else if (nread == 0)
@@ -4058,16 +4053,13 @@ by calling `format-decode', which see. */)
4058 inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */ 4053 inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */
4059 unprocessed = 0; /* Bytes not processed in previous loop. */ 4054 unprocessed = 0; /* Bytes not processed in previous loop. */
4060 4055
4061 while (1) 4056 while (true)
4062 { 4057 {
4063 /* Read at most READ_BUF_SIZE bytes at a time, to allow 4058 /* Read at most READ_BUF_SIZE bytes at a time, to allow
4064 quitting while reading a huge file. */ 4059 quitting while reading a huge file. */
4065 4060
4066 /* Allow quitting out of the actual I/O. */ 4061 this = emacs_read_quit (fd, read_buf + unprocessed,
4067 maybe_quit (); 4062 READ_BUF_SIZE - unprocessed);
4068 this = emacs_read (fd, read_buf + unprocessed,
4069 READ_BUF_SIZE - unprocessed);
4070
4071 if (this <= 0) 4063 if (this <= 0)
4072 break; 4064 break;
4073 4065
@@ -4281,11 +4273,10 @@ by calling `format-decode', which see. */)
4281 /* Allow quitting out of the actual I/O. We don't make text 4273 /* Allow quitting out of the actual I/O. We don't make text
4282 part of the buffer until all the reading is done, so a C-g 4274 part of the buffer until all the reading is done, so a C-g
4283 here doesn't do any harm. */ 4275 here doesn't do any harm. */
4284 maybe_quit (); 4276 this = emacs_read_quit (fd,
4285 this = emacs_read (fd, 4277 ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE
4286 ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE 4278 + inserted),
4287 + inserted), 4279 trytry);
4288 trytry);
4289 } 4280 }
4290 4281
4291 if (this <= 0) 4282 if (this <= 0)
@@ -5398,7 +5389,7 @@ e_write (int desc, Lisp_Object string, ptrdiff_t start, ptrdiff_t end,
5398 : (STRINGP (coding->dst_object) 5389 : (STRINGP (coding->dst_object)
5399 ? SSDATA (coding->dst_object) 5390 ? SSDATA (coding->dst_object)
5400 : (char *) BYTE_POS_ADDR (coding->dst_pos_byte))); 5391 : (char *) BYTE_POS_ADDR (coding->dst_pos_byte)));
5401 coding->produced -= emacs_write_sig (desc, buf, coding->produced); 5392 coding->produced -= emacs_write_quit (desc, buf, coding->produced);
5402 5393
5403 if (coding->raw_destination) 5394 if (coding->raw_destination)
5404 { 5395 {