From 386a3da920482b8cb3e962fb944d135c8a770e26 Mon Sep 17 00:00:00 2001 From: Martin Rudalics Date: Thu, 22 Jun 2017 09:24:06 +0200 Subject: [PATCH 1/6] Fix make_hash_table calls in lread.c * src/lread.c (readevalloop, read_internal_start): Fix make_hash_table calls to make build succeed. --- src/lread.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lread.c b/src/lread.c index b01cbd5c072..8716b86e9bf 100644 --- a/src/lread.c +++ b/src/lread.c @@ -1942,13 +1942,13 @@ readevalloop (Lisp_Object readcharfun, read_objects_map = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, DEFAULT_REHASH_SIZE, DEFAULT_REHASH_THRESHOLD, - Qnil, Qnil); + Qnil, false); if (! HASH_TABLE_P (read_objects_completed) || XHASH_TABLE (read_objects_completed)->count) read_objects_completed = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, DEFAULT_REHASH_SIZE, DEFAULT_REHASH_THRESHOLD, - Qnil, Qnil); + Qnil, false); if (!NILP (Vpurify_flag) && c == '(') { val = read_list (0, readcharfun); @@ -2159,12 +2159,12 @@ read_internal_start (Lisp_Object stream, Lisp_Object start, Lisp_Object end) || XHASH_TABLE (read_objects_map)->count) read_objects_map = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, DEFAULT_REHASH_SIZE, - DEFAULT_REHASH_THRESHOLD, Qnil, Qnil); + DEFAULT_REHASH_THRESHOLD, Qnil, false); if (! HASH_TABLE_P (read_objects_completed) || XHASH_TABLE (read_objects_completed)->count) read_objects_completed = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, DEFAULT_REHASH_SIZE, - DEFAULT_REHASH_THRESHOLD, Qnil, Qnil); + DEFAULT_REHASH_THRESHOLD, Qnil, false); if (EQ (Vread_with_symbol_positions, Qt) || EQ (Vread_with_symbol_positions, stream)) Vread_symbol_positions_list = Qnil; From 0ee2e853abfe2c6ed1f4fd105c0a52fd93b271fb Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Thu, 22 Jun 2017 09:47:48 -0400 Subject: [PATCH 2/6] * lisp/descr-text.el (describe-char): Avoid string-*-multibyte Avoid string-to-multibyte and string-as-unibyte. Don't make *Help* unibyte just because the char was in a unibyte buffer. --- lisp/descr-text.el | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lisp/descr-text.el b/lisp/descr-text.el index 6a6a8ea4479..6f36bbed680 100644 --- a/lisp/descr-text.el +++ b/lisp/descr-text.el @@ -413,12 +413,11 @@ relevant to POS." (multibyte-p enable-multibyte-characters) (overlays (mapcar (lambda (o) (overlay-properties o)) (overlays-at pos))) - (char-description (if (not multibyte-p) + (char-description (if (< char 128) (single-key-description char) - (if (< char 128) - (single-key-description char) - (string-to-multibyte - (char-to-string char))))) + (string (if (not multibyte-p) + (decode-char 'eight-bit char) + char)))) (text-props-desc (let ((tmp-buf (generate-new-buffer " *text-props*"))) (unwind-protect @@ -635,7 +634,9 @@ relevant to POS." ("buffer code" ,(if multibyte-p (encoded-string-description - (string-as-unibyte (char-to-string char)) nil) + (encode-coding-string (char-to-string char) + 'emacs-internal) + nil) (format "#x%02X" char))) ("file code" ,@(if multibyte-p @@ -704,7 +705,6 @@ relevant to POS." (called-interactively-p 'interactive)) (with-help-window (help-buffer) (with-current-buffer standard-output - (set-buffer-multibyte multibyte-p) (let ((formatter (format "%%%ds:" max-width))) (dolist (elt item-list) (when (cadr elt) From 21132e2623dddd19be421ba326434e3cffb1019b Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Mon, 19 Jun 2017 21:34:25 +0200 Subject: [PATCH 3/6] =?UTF-8?q?unidata:=20don=E2=80=99t=20check=20special?= =?UTF-8?q?=20casing=20in=20unidata-check=20=20(bug#26656)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * admin/unidata/unidata-gen.el (unidata-check): Do not test special casing mapping of characters since that mapping is not constructed from the unidata.txt file. Also, check for integer decoder and cons char earlier so that less unnecessary processing is performed. --- admin/unidata/unidata-gen.el | 94 +++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 44 deletions(-) diff --git a/admin/unidata/unidata-gen.el b/admin/unidata/unidata-gen.el index e1e896ce29c..478099c831a 100644 --- a/admin/unidata/unidata-gen.el +++ b/admin/unidata/unidata-gen.el @@ -1346,50 +1346,56 @@ Property value is a symbol `o' (Open), `c' (Close), or `n' (None)." (generator (unidata-prop-generator proplist)) (default-value (unidata-prop-default proplist)) (val-list (unidata-prop-val-list proplist)) - (table (progn - (message "Generating %S table..." prop) - (funcall generator prop index default-value val-list))) - (decoder (char-table-extra-slot table 1)) - (alist (and (functionp index) - (funcall index))) - (check #x400)) - (dolist (e unidata-list) - (let* ((char (car e)) - (val1 - (if alist (nth 1 (assoc char alist)) - (nth index e))) - val2) - (if (and (stringp val1) (= (length val1) 0)) - (setq val1 nil)) - (unless (or (consp char) - (integerp decoder)) - (setq val2 - (cond ((functionp decoder) - (funcall decoder char (aref table char) table)) - (t ; must be nil - (aref table char)))) - (if val1 - (cond ((eq generator 'unidata-gen-table-symbol) - (setq val1 (intern val1))) - ((eq generator 'unidata-gen-table-integer) - (setq val1 (string-to-number val1))) - ((eq generator 'unidata-gen-table-character) - (setq val1 (string-to-number val1 16))) - ((eq generator 'unidata-gen-table-decomposition) - (setq val1 (unidata-split-decomposition val1)))) - (cond ((eq prop 'decomposition) - (setq val1 (list char))) - ((eq prop 'bracket-type) - (setq val1 'n)))) - (when (>= char check) - (message "%S %04X" prop check) - (setq check (+ check #x400))) - (or (equal val1 val2) - ;; characters get a 'name' property of nil - (and (eq prop 'name) (string= val1 "") (null val2)) - (insert (format "> %04X %S\n< %04X %S\n" - char val1 char val2))) - (sit-for 0)))))))) + (check #x400) + table decoder alist) + ;; We compare values in unidata.txt with the ones returned by various + ;; generator functions. However, SpecialCasing.txt is read directly by + ;; unidata-gen-table-special-casing--do-load and there is no other file + ;; to compare those values with. This is why we’re skipping the check + ;; for special casing properties. + (unless (eq generator 'unidata-gen-table-special-casing) + (setq table (progn + (message "Generating %S table..." prop) + (funcall generator prop index default-value val-list)) + decoder (char-table-extra-slot table 1)) + (unless (integerp decoder) + (setq alist (and (functionp index) (funcall index))) + (dolist (e unidata-list) + (let ((char (car e)) val1 val2) + (unless (consp char) + (setq val1 (if alist + (nth 1 (assoc char alist)) + (nth index e))) + (and (stringp val1) + (= (length val1) 0) + (setq val1 nil)) + (if val1 + (cond ((eq generator 'unidata-gen-table-symbol) + (setq val1 (intern val1))) + ((eq generator 'unidata-gen-table-integer) + (setq val1 (string-to-number val1))) + ((eq generator 'unidata-gen-table-character) + (setq val1 (string-to-number val1 16))) + ((eq generator 'unidata-gen-table-decomposition) + (setq val1 (unidata-split-decomposition val1)))) + (cond ((eq prop 'decomposition) + (setq val1 (list char))) + ((eq prop 'bracket-type) + (setq val1 'n)))) + (setq val2 (aref table char)) + (when decoder + (setq val2 (funcall decoder char val2 table))) + (when (>= char check) + (message "%S %04X" prop check) + (setq check (+ check #x400))) + (or (equal val1 val2) + ;; characters get a 'name' property of nil + (and (eq prop 'name) + (string= val1 "") + (null val2)) + (insert (format "> %04X %S\n< %04X %S\n" + char val1 char val2))) + (sit-for 0)))))))))) ;; The entry functions. They generate files described in the header ;; comment of this file. From 18896f79136bb7d6d4c0c6b1d066b4e82644db6a Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Thu, 22 Jun 2017 14:11:29 -0400 Subject: [PATCH 4/6] * lisp/net/shr.el (shr-fill-text): Actually fill the text. (Bug#27399) --- lisp/net/shr.el | 1 + 1 file changed, 1 insertion(+) diff --git a/lisp/net/shr.el b/lisp/net/shr.el index 2a6b3960c46..45ef379af54 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el @@ -512,6 +512,7 @@ size, and full-buffer size." (* (frame-char-width) 2) 0)))) (shr-insert text) + (shr-fill-lines (point-min) (point-max)) (buffer-string))))) (define-inline shr-char-breakable-p (char) From f6ef15cf84c1288e972ef0e6165b97e34d6033b6 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 22 Jun 2017 11:21:20 -0700 Subject: [PATCH 5/6] Use unlocked stdio more systematically This can improve performance significantly on stdio-bottlenecked code. E.g., make-docfile is 3x faster on my Fedora 25 x86-64 desktop. * admin/merge-gnulib (GNULIB_MODULES): Add unlocked-io. * lib-src/ebrowse.c, lib-src/emacsclient.c, lib-src/etags.c: * lib-src/hexl.c, lib-src/make-docfile.c, lib-src/movemail.c: * lib-src/profile.c, lib-src/update-game-score.c: Include unlocked-io.h instead of stdio.h, since these programs are single-threaded. * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate. * lib/unlocked-io.h, m4/unlocked-io.m4: New files, copied from Gnulib. * src/charset.c, src/cm.c, src/emacs.c, src/image.c, src/keyboard.c: * src/lread.c, src/term.c: Include sysstdio.h, possibly instead of stdio.h, to define the unlocked functions if the system does not provide them. * src/charset.c, src/lread.c (getc_unlocked): Remove, since sysstdio.h now defines it if needed. * src/cm.c (cmputc, cmcheckmagic): * src/dispnew.c (update_frame, update_frame_with_menu) (update_frame_1, Fsend_string_to_terminal, Fding, bitch_at_user): * src/emacs.c (main, Fdump_emacs): * src/fileio.c (Fdo_auto_save, Fset_binary_mode): * src/image.c (slurp_file, png_read_from_file, png_load_body) (our_stdio_fill_input_buffer): * src/keyboard.c (record_char, kbd_buffer_get_event, handle_interrupt): * src/lread.c (readbyte_from_file): * src/minibuf.c (read_minibuf_noninteractive): * src/print.c (printchar_to_stream, strout) (Fredirect_debugging_output): * src/sysdep.c (reset_sys_modes, procfs_ttyname) (procfs_get_total_memory): * src/term.c (tty_ring_bell, tty_send_additional_strings) (tty_set_terminal_modes, tty_reset_terminal_modes) (tty_update_end, tty_clear_end_of_line, tty_write_glyphs) (tty_write_glyphs_with_face, tty_insert_glyphs) (tty_menu_activate): * src/xfaces.c (Fx_load_color_file): Use unlocked stdio when it should be safe. * src/sysstdio.h (clearerr_unlocked, feof_unlocked, ferror_unlocked) (fflush_unlocked, fgets_unlocked, fputc_unlocked, fputs_unlocked) (fread_unlocked, fwrite_unlocked, getc_unlocked, getchar_unlocked) (putc_unlocked, putchar_unloced): Provide substitutes if not declared. --- admin/merge-gnulib | 2 +- lib-src/ebrowse.c | 8 +-- lib-src/emacsclient.c | 3 +- lib-src/etags.c | 1 + lib-src/hexl.c | 2 +- lib-src/make-docfile.c | 10 +-- lib-src/movemail.c | 4 +- lib-src/profile.c | 2 +- lib-src/update-game-score.c | 3 +- lib/gnulib.mk.in | 11 ++- lib/unlocked-io.h | 136 ++++++++++++++++++++++++++++++++++++ m4/gnulib-comp.m4 | 4 ++ m4/unlocked-io.m4 | 41 +++++++++++ src/charset.c | 6 +- src/cm.c | 14 ++-- src/dispnew.c | 22 +++--- src/emacs.c | 8 +-- src/fileio.c | 16 ++--- src/image.c | 11 +-- src/keyboard.c | 19 ++--- src/lread.c | 11 +-- src/minibuf.c | 8 +-- src/print.c | 10 +-- src/sysdep.c | 15 ++-- src/sysstdio.h | 41 +++++++++++ src/term.c | 47 +++++++------ src/xfaces.c | 2 +- 27 files changed, 341 insertions(+), 116 deletions(-) create mode 100644 lib/unlocked-io.h create mode 100644 m4/unlocked-io.m4 diff --git a/admin/merge-gnulib b/admin/merge-gnulib index d4bbf17cb3d..85921ba1ba6 100755 --- a/admin/merge-gnulib +++ b/admin/merge-gnulib @@ -40,7 +40,7 @@ GNULIB_MODULES=' sig2str socklen stat-time std-gnu11 stdalign stddef stdio stpcpy strftime strtoimax symlink sys_stat sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub - update-copyright utimens + update-copyright unlocked-io utimens vla warnings ' diff --git a/lib-src/ebrowse.c b/lib-src/ebrowse.c index 51d181997b1..e77b7c94cca 100644 --- a/lib-src/ebrowse.c +++ b/lib-src/ebrowse.c @@ -20,21 +20,21 @@ along with GNU Emacs. If not, see . */ #include #include -#include #include #include #include #include #include +#include +#include +#include + /* The SunOS compiler doesn't have SEEK_END. */ #ifndef SEEK_END #define SEEK_END 2 #endif -#include -#include - /* Files are read in chunks of this number of bytes. */ enum { READ_CHUNK_SIZE = 100 * 1024 }; diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c index 8828b7652de..f1d4e8976da 100644 --- a/lib-src/emacsclient.c +++ b/lib-src/emacsclient.c @@ -73,7 +73,6 @@ char *w32_getenv (const char *); #include #include -#include #include #include #include @@ -84,6 +83,8 @@ char *w32_getenv (const char *); #include #include +#include + #ifndef VERSION #define VERSION "unspecified" #endif diff --git a/lib-src/etags.c b/lib-src/etags.c index 6f280d8ab40..e5ff7bd10fc 100644 --- a/lib-src/etags.c +++ b/lib-src/etags.c @@ -123,6 +123,7 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4"; #include #include #include +#include #include #include diff --git a/lib-src/hexl.c b/lib-src/hexl.c index 319ce8bc890..d949af08902 100644 --- a/lib-src/hexl.c +++ b/lib-src/hexl.c @@ -22,11 +22,11 @@ along with this program. If not, see . */ #include #include -#include #include #include #include +#include static char *progname; diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c index 9470bd635f5..6b2cc110403 100644 --- a/lib-src/make-docfile.c +++ b/lib-src/make-docfile.c @@ -39,10 +39,14 @@ along with GNU Emacs. If not, see . */ #include #include #include -#include #include #include +#include +#include +#include +#include + #ifdef WINDOWSNT /* Defined to be sys_fopen in ms-w32.h, but only #ifdef emacs, so this is really just insurance. */ @@ -50,10 +54,6 @@ along with GNU Emacs. If not, see . */ #include #endif /* WINDOWSNT */ -#include -#include -#include - #ifdef DOS_NT /* Defined to be sys_chdir in ms-w32.h, but only #ifdef emacs, so this is really just insurance. diff --git a/lib-src/movemail.c b/lib-src/movemail.c index cd12c48ed36..e5ca0b16611 100644 --- a/lib-src/movemail.c +++ b/lib-src/movemail.c @@ -59,7 +59,6 @@ along with GNU Emacs. If not, see . */ #include #include #include -#include #include #include #include @@ -69,6 +68,9 @@ along with GNU Emacs. If not, see . */ #include #include #include + +#include + #include "syswait.h" #ifdef MAIL_USE_POP #include "pop.h" diff --git a/lib-src/profile.c b/lib-src/profile.c index 253f00e2d80..f4ab45c1718 100644 --- a/lib-src/profile.c +++ b/lib-src/profile.c @@ -34,11 +34,11 @@ along with GNU Emacs. If not, see . */ #include #include -#include #include #include #include +#include static struct timespec TV1; static int watch_not_started = 1; /* flag */ diff --git a/lib-src/update-game-score.c b/lib-src/update-game-score.c index 5edc8e79569..942aeeb399d 100644 --- a/lib-src/update-game-score.c +++ b/lib-src/update-game-score.c @@ -39,7 +39,6 @@ along with GNU Emacs. If not, see . */ #include #include #include -#include #include #include #include @@ -47,6 +46,8 @@ along with GNU Emacs. If not, see . */ #include #include +#include + #ifdef WINDOWSNT #include "ntlib.h" #endif diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index 509089e6391..fd0f9e5c780 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in @@ -21,7 +21,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=setenv --avoid=sigprocmask --avoid=stat --avoid=stdarg --avoid=stdbool --avoid=threadlib --avoid=tzset --avoid=unsetenv --avoid=utime --avoid=utime-h --gnu-make --makefile-name=gnulib.mk.in --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt binary-io byteswap c-ctype c-strcase careadlinkat close-stream count-leading-zeros count-one-bits count-trailing-zeros crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 diffseq dtoastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir filemode filevercmp flexmember fstatat fsync getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog ignore-value intprops largefile lstat manywarnings memrchr minmax mkostemp mktime pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat sig2str socklen stat-time std-gnu11 stdalign stddef stdio stpcpy strftime strtoimax symlink sys_stat sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub update-copyright utimens vla warnings +# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=setenv --avoid=sigprocmask --avoid=stat --avoid=stdarg --avoid=stdbool --avoid=threadlib --avoid=tzset --avoid=unsetenv --avoid=utime --avoid=utime-h --gnu-make --makefile-name=gnulib.mk.in --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt binary-io byteswap c-ctype c-strcase careadlinkat close-stream count-leading-zeros count-one-bits count-trailing-zeros crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 diffseq dtoastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir filemode filevercmp flexmember fstatat fsync getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog ignore-value intprops largefile lstat manywarnings memrchr minmax mkostemp mktime pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat sig2str socklen stat-time std-gnu11 stdalign stddef stdio stpcpy strftime strtoimax symlink sys_stat sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub unlocked-io update-copyright utimens vla warnings MOSTLYCLEANFILES += core *.stackdump @@ -2996,6 +2996,15 @@ EXTRA_DIST += unistd.in.h endif ## end gnulib module unistd +## begin gnulib module unlocked-io +ifeq (,$(OMIT_GNULIB_MODULE_unlocked-io)) + + +EXTRA_DIST += unlocked-io.h + +endif +## end gnulib module unlocked-io + ## begin gnulib module update-copyright ifeq (,$(OMIT_GNULIB_MODULE_update-copyright)) diff --git a/lib/unlocked-io.h b/lib/unlocked-io.h new file mode 100644 index 00000000000..aaf60a0fb4e --- /dev/null +++ b/lib/unlocked-io.h @@ -0,0 +1,136 @@ +/* Prefer faster, non-thread-safe stdio functions if available. + + Copyright (C) 2001-2004, 2009-2017 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Jim Meyering. */ + +#ifndef UNLOCKED_IO_H +# define UNLOCKED_IO_H 1 + +/* These are wrappers for functions/macros from the GNU C library, and + from other C libraries supporting POSIX's optional thread-safe functions. + + The standard I/O functions are thread-safe. These *_unlocked ones are + more efficient but not thread-safe. That they're not thread-safe is + fine since all of the applications in this package are single threaded. + + Also, some code that is shared with the GNU C library may invoke + the *_unlocked functions directly. On hosts that lack those + functions, invoke the non-thread-safe versions instead. */ + +# include + +# if HAVE_DECL_CLEARERR_UNLOCKED +# undef clearerr +# define clearerr(x) clearerr_unlocked (x) +# else +# define clearerr_unlocked(x) clearerr (x) +# endif + +# if HAVE_DECL_FEOF_UNLOCKED +# undef feof +# define feof(x) feof_unlocked (x) +# else +# define feof_unlocked(x) feof (x) +# endif + +# if HAVE_DECL_FERROR_UNLOCKED +# undef ferror +# define ferror(x) ferror_unlocked (x) +# else +# define ferror_unlocked(x) ferror (x) +# endif + +# if HAVE_DECL_FFLUSH_UNLOCKED +# undef fflush +# define fflush(x) fflush_unlocked (x) +# else +# define fflush_unlocked(x) fflush (x) +# endif + +# if HAVE_DECL_FGETS_UNLOCKED +# undef fgets +# define fgets(x,y,z) fgets_unlocked (x,y,z) +# else +# define fgets_unlocked(x,y,z) fgets (x,y,z) +# endif + +# if HAVE_DECL_FPUTC_UNLOCKED +# undef fputc +# define fputc(x,y) fputc_unlocked (x,y) +# else +# define fputc_unlocked(x,y) fputc (x,y) +# endif + +# if HAVE_DECL_FPUTS_UNLOCKED +# undef fputs +# define fputs(x,y) fputs_unlocked (x,y) +# else +# define fputs_unlocked(x,y) fputs (x,y) +# endif + +# if HAVE_DECL_FREAD_UNLOCKED +# undef fread +# define fread(w,x,y,z) fread_unlocked (w,x,y,z) +# else +# define fread_unlocked(w,x,y,z) fread (w,x,y,z) +# endif + +# if HAVE_DECL_FWRITE_UNLOCKED +# undef fwrite +# define fwrite(w,x,y,z) fwrite_unlocked (w,x,y,z) +# else +# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z) +# endif + +# if HAVE_DECL_GETC_UNLOCKED +# undef getc +# define getc(x) getc_unlocked (x) +# else +# define getc_unlocked(x) getc (x) +# endif + +# if HAVE_DECL_GETCHAR_UNLOCKED +# undef getchar +# define getchar() getchar_unlocked () +# else +# define getchar_unlocked() getchar () +# endif + +# if HAVE_DECL_PUTC_UNLOCKED +# undef putc +# define putc(x,y) putc_unlocked (x,y) +# else +# define putc_unlocked(x,y) putc (x,y) +# endif + +# if HAVE_DECL_PUTCHAR_UNLOCKED +# undef putchar +# define putchar(x) putchar_unlocked (x) +# else +# define putchar_unlocked(x) putchar (x) +# endif + +# undef flockfile +# define flockfile(x) ((void) 0) + +# undef ftrylockfile +# define ftrylockfile(x) 0 + +# undef funlockfile +# define funlockfile(x) ((void) 0) + +#endif /* UNLOCKED_IO_H */ diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index 1ac58e871cc..107645df4fd 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -158,6 +158,7 @@ AC_DEFUN([gl_EARLY], # Code from module timespec-sub: # Code from module u64: # Code from module unistd: + # Code from module unlocked-io: # Code from module update-copyright: # Code from module utimens: # Code from module vararrays: @@ -399,6 +400,7 @@ AC_DEFUN([gl_INIT], gl_TIMER_TIME gl_TIMESPEC gl_UNISTD_H + gl_FUNC_GLIBC_UNLOCKED_IO gl_UTIMENS AC_C_VARARRAYS gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b=false @@ -940,6 +942,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/u64.h lib/unistd.c lib/unistd.in.h + lib/unlocked-io.h lib/utimens.c lib/utimens.h lib/verify.h @@ -1044,6 +1047,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/timespec.m4 m4/tm_gmtoff.m4 m4/unistd_h.m4 + m4/unlocked-io.m4 m4/utimens.m4 m4/utimes.m4 m4/vararrays.m4 diff --git a/m4/unlocked-io.m4 b/m4/unlocked-io.m4 new file mode 100644 index 00000000000..448ccac2f0e --- /dev/null +++ b/m4/unlocked-io.m4 @@ -0,0 +1,41 @@ +# unlocked-io.m4 serial 15 + +# Copyright (C) 1998-2006, 2009-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +dnl From Jim Meyering. +dnl +dnl See if the glibc *_unlocked I/O macros or functions are available. +dnl Use only those *_unlocked macros or functions that are declared +dnl (because some of them were declared in Solaris 2.5.1 but were removed +dnl in Solaris 2.6, whereas we want binaries built on Solaris 2.5.1 to run +dnl on Solaris 2.6). + +AC_DEFUN([gl_FUNC_GLIBC_UNLOCKED_IO], +[ + AC_DEFINE([USE_UNLOCKED_IO], [1], + [Define to 1 if you want getc etc. to use unlocked I/O if available. + Unlocked I/O can improve performance in unithreaded apps, + but it is not safe for multithreaded apps.]) + + dnl Persuade glibc and Solaris to declare + dnl fgets_unlocked(), fputs_unlocked() etc. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + AC_CHECK_DECLS_ONCE([clearerr_unlocked]) + AC_CHECK_DECLS_ONCE([feof_unlocked]) + AC_CHECK_DECLS_ONCE([ferror_unlocked]) + AC_CHECK_DECLS_ONCE([fflush_unlocked]) + AC_CHECK_DECLS_ONCE([fgets_unlocked]) + AC_CHECK_DECLS_ONCE([fputc_unlocked]) + AC_CHECK_DECLS_ONCE([fputs_unlocked]) + AC_CHECK_DECLS_ONCE([fread_unlocked]) + AC_CHECK_DECLS_ONCE([fwrite_unlocked]) + AC_CHECK_DECLS_ONCE([getc_unlocked]) + AC_CHECK_DECLS_ONCE([getchar_unlocked]) + AC_CHECK_DECLS_ONCE([putc_unlocked]) + AC_CHECK_DECLS_ONCE([putchar_unlocked]) +]) diff --git a/src/charset.c b/src/charset.c index 9d15375dd79..d0840f7d2a9 100644 --- a/src/charset.c +++ b/src/charset.c @@ -29,7 +29,6 @@ along with GNU Emacs. If not, see . */ #include #include -#include #include #include #include @@ -40,6 +39,7 @@ along with GNU Emacs. If not, see . */ #include "charset.h" #include "coding.h" #include "buffer.h" +#include "sysstdio.h" /*** GENERAL NOTES on CODED CHARACTER SETS (CHARSETS) *** @@ -198,10 +198,6 @@ static struct #define GET_TEMP_CHARSET_WORK_DECODER(CODE) \ (temp_charset_work->table.decoder[(CODE)]) - -#ifndef HAVE_GETC_UNLOCKED -#define getc_unlocked getc -#endif /* Set to 1 to warn that a charset map is loaded and thus a buffer diff --git a/src/cm.c b/src/cm.c index efa50b0f58d..9a90f37445c 100644 --- a/src/cm.c +++ b/src/cm.c @@ -19,10 +19,10 @@ along with GNU Emacs. If not, see . */ #include -#include #include "lisp.h" #include "cm.h" +#include "sysstdio.h" #include "termchar.h" #include "tparam.h" @@ -45,8 +45,8 @@ int cmputc (int c) { if (current_tty->termscript) - putc (c & 0177, current_tty->termscript); - putc (c & 0177, current_tty->output); + putc_unlocked (c & 0177, current_tty->termscript); + putc_unlocked (c & 0177, current_tty->output); return c; } @@ -117,11 +117,11 @@ cmcheckmagic (struct tty_display_info *tty) if (!MagicWrap (tty) || curY (tty) >= FrameRows (tty) - 1) emacs_abort (); if (tty->termscript) - putc ('\r', tty->termscript); - putc ('\r', tty->output); + putc_unlocked ('\r', tty->termscript); + putc_unlocked ('\r', tty->output); if (tty->termscript) - putc ('\n', tty->termscript); - putc ('\n', tty->output); + putc_unlocked ('\n', tty->termscript); + putc_unlocked ('\n', tty->output); curX (tty) = 0; curY (tty)++; } diff --git a/src/dispnew.c b/src/dispnew.c index 27c69bde831..925e44d9804 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -3126,9 +3126,9 @@ update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p) if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)) { if (FRAME_TTY (f)->termscript) - fflush (FRAME_TTY (f)->termscript); + fflush_unlocked (FRAME_TTY (f)->termscript); if (FRAME_TERMCAP_P (f)) - fflush (FRAME_TTY (f)->output); + fflush_unlocked (FRAME_TTY (f)->output); } /* Check window matrices for lost pointers. */ @@ -3181,8 +3181,8 @@ update_frame_with_menu (struct frame *f, int row, int col) update_end (f); if (FRAME_TTY (f)->termscript) - fflush (FRAME_TTY (f)->termscript); - fflush (FRAME_TTY (f)->output); + fflush_unlocked (FRAME_TTY (f)->termscript); + fflush_unlocked (FRAME_TTY (f)->output); /* Check window matrices for lost pointers. */ #if GLYPH_DEBUG #if 0 @@ -4531,7 +4531,7 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p, ptrdiff_t outq = __fpending (display_output); if (outq > 900 || (outq > 20 && ((i - 1) % preempt_count == 0))) - fflush (display_output); + fflush_unlocked (display_output); } } @@ -5615,13 +5615,13 @@ when TERMINAL is nil. */) if (tty->termscript) { - fwrite (SDATA (string), 1, SBYTES (string), tty->termscript); - fflush (tty->termscript); + fwrite_unlocked (SDATA (string), 1, SBYTES (string), tty->termscript); + fflush_unlocked (tty->termscript); } out = tty->output; } - fwrite (SDATA (string), 1, SBYTES (string), out); - fflush (out); + fwrite_unlocked (SDATA (string), 1, SBYTES (string), out); + fflush_unlocked (out); unblock_input (); return Qnil; } @@ -5636,7 +5636,7 @@ terminate any keyboard macro currently executing. */) if (!NILP (arg)) { if (noninteractive) - putchar (07); + putchar_unlocked (07); else ring_bell (XFRAME (selected_frame)); } @@ -5650,7 +5650,7 @@ void bitch_at_user (void) { if (noninteractive) - putchar (07); + putchar_unlocked (07); else if (!INTERACTIVE) /* Stop executing a keyboard macro. */ { const char *msg diff --git a/src/emacs.c b/src/emacs.c index da8df1bf1c7..0fec7167588 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -23,7 +23,6 @@ along with GNU Emacs. If not, see . */ #include #include -#include #include #include @@ -33,6 +32,7 @@ along with GNU Emacs. If not, see . */ #define MAIN_PROGRAM #include "lisp.h" +#include "sysstdio.h" #ifdef WINDOWSNT #include @@ -885,7 +885,7 @@ main (int argc, char **argv) } #endif /* HAVE_SETRLIMIT and RLIMIT_STACK and not CYGWIN */ - clearerr (stdin); + clearerr_unlocked (stdin); emacs_backtrace (-1); @@ -983,7 +983,7 @@ main (int argc, char **argv) int i; printf ("Usage: %s [OPTION-OR-FILENAME]...\n", argv[0]); for (i = 0; i < ARRAYELTS (usage_message); i++) - fputs (usage_message[i], stdout); + fputs_unlocked (usage_message[i], stdout); exit (0); } @@ -2197,7 +2197,7 @@ You must run Emacs in batch mode in order to dump it. */) } #endif - fflush (stdout); + fflush_unlocked (stdout); /* Tell malloc where start of impure now is. */ /* Also arrange for warnings when nearly out of space. */ #if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC diff --git a/src/fileio.c b/src/fileio.c index cb070029a9b..a57d50b24e0 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -5643,14 +5643,12 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */) { block_input (); if (!NILP (BVAR (b, filename))) - { - fwrite (SDATA (BVAR (b, filename)), 1, - SBYTES (BVAR (b, filename)), stream); - } - putc ('\n', stream); - fwrite (SDATA (BVAR (b, auto_save_file_name)), 1, - SBYTES (BVAR (b, auto_save_file_name)), stream); - putc ('\n', stream); + fwrite_unlocked (SDATA (BVAR (b, filename)), 1, + SBYTES (BVAR (b, filename)), stream); + putc_unlocked ('\n', stream); + fwrite_unlocked (SDATA (BVAR (b, auto_save_file_name)), 1, + SBYTES (BVAR (b, auto_save_file_name)), stream); + putc_unlocked ('\n', stream); unblock_input (); } @@ -5841,7 +5839,7 @@ effect except for flushing STREAM's data. */) binmode = NILP (mode) ? O_TEXT : O_BINARY; if (fp != stdin) - fflush (fp); + fflush_unlocked (fp); return (set_binary_mode (fileno (fp), binmode) == O_BINARY) ? Qt : Qnil; } diff --git a/src/image.c b/src/image.c index aedec7954ee..07c4769e9e3 100644 --- a/src/image.c +++ b/src/image.c @@ -20,7 +20,6 @@ along with GNU Emacs. If not, see . */ #include #include -#include #include /* Include this before including to work around bugs with @@ -41,6 +40,7 @@ along with GNU Emacs. If not, see . */ #include "buffer.h" #include "dispextern.h" #include "blockinput.h" +#include "sysstdio.h" #include "systime.h" #include #include "coding.h" @@ -2361,7 +2361,7 @@ slurp_file (int fd, ptrdiff_t *size) This can happen if the file grows as we read it. */ ptrdiff_t buflen = st.st_size; buf = xmalloc (buflen + 1); - if (fread (buf, 1, buflen + 1, fp) == buflen) + if (fread_unlocked (buf, 1, buflen + 1, fp) == buflen) *size = buflen; else { @@ -5890,7 +5890,7 @@ png_read_from_file (png_structp png_ptr, png_bytep data, png_size_t length) { FILE *fp = png_get_io_ptr (png_ptr); - if (fread (data, 1, length, fp) < length) + if (fread_unlocked (data, 1, length, fp) < length) png_error (png_ptr, "Read error"); } @@ -5959,7 +5959,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) } /* Check PNG signature. */ - if (fread (sig, 1, sizeof sig, fp) != sizeof sig + if (fread_unlocked (sig, 1, sizeof sig, fp) != sizeof sig || png_sig_cmp (sig, 0, sizeof sig)) { fclose (fp); @@ -6598,7 +6598,8 @@ our_stdio_fill_input_buffer (j_decompress_ptr cinfo) { ptrdiff_t bytes; - bytes = fread (src->buffer, 1, JPEG_STDIO_BUFFER_SIZE, src->file); + bytes = fread_unlocked (src->buffer, 1, JPEG_STDIO_BUFFER_SIZE, + src->file); if (bytes > 0) src->mgr.bytes_in_buffer = bytes; else diff --git a/src/keyboard.c b/src/keyboard.c index 55486c6d9ab..3442b18409a 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -39,6 +39,7 @@ along with GNU Emacs. If not, see . */ #include "intervals.h" #include "keymap.h" #include "blockinput.h" +#include "sysstdio.h" #include "systime.h" #include "atimer.h" #include "process.h" @@ -3290,7 +3291,7 @@ record_char (Lisp_Object c) if (INTEGERP (c)) { if (XUINT (c) < 0x100) - putc (XUINT (c), dribble); + putc_unlocked (XUINT (c), dribble); else fprintf (dribble, " 0x%"pI"x", XUINT (c)); } @@ -3303,15 +3304,15 @@ record_char (Lisp_Object c) if (SYMBOLP (dribblee)) { - putc ('<', dribble); - fwrite (SDATA (SYMBOL_NAME (dribblee)), sizeof (char), - SBYTES (SYMBOL_NAME (dribblee)), - dribble); - putc ('>', dribble); + putc_unlocked ('<', dribble); + fwrite_unlocked (SDATA (SYMBOL_NAME (dribblee)), sizeof (char), + SBYTES (SYMBOL_NAME (dribblee)), + dribble); + putc_unlocked ('>', dribble); } } - fflush (dribble); + fflush_unlocked (dribble); unblock_input (); } } @@ -3769,7 +3770,7 @@ kbd_buffer_get_event (KBOARD **kbp, detaching from the terminal. */ || (IS_DAEMON && DAEMON_RUNNING)) { - int c = getchar (); + int c = getchar_unlocked (); XSETINT (obj, c); *kbp = current_kboard; return obj; @@ -10377,7 +10378,7 @@ handle_interrupt (bool in_signal_handler) sigemptyset (&blocked); sigaddset (&blocked, SIGINT); pthread_sigmask (SIG_BLOCK, &blocked, 0); - fflush (stdout); + fflush_unlocked (stdout); } reset_all_sys_modes (); diff --git a/src/lread.c b/src/lread.c index 8716b86e9bf..182f96223a5 100644 --- a/src/lread.c +++ b/src/lread.c @@ -72,10 +72,6 @@ along with GNU Emacs. If not, see . */ #define file_tell ftell #endif -#ifndef HAVE_GETC_UNLOCKED -#define getc_unlocked getc -#endif - /* The objects or placeholders read with the #n=object form. A hash table maps a number to either a placeholder (while the @@ -474,16 +470,15 @@ readbyte_from_file (int c, Lisp_Object readcharfun) } block_input (); - c = getc_unlocked (instream); /* Interrupted reads have been observed while reading over the network. */ - while (c == EOF && ferror (instream) && errno == EINTR) + while ((c = getc_unlocked (instream)) == EOF && errno == EINTR + && ferror_unlocked (instream)) { unblock_input (); maybe_quit (); block_input (); - clearerr (instream); - c = getc_unlocked (instream); + clearerr_unlocked (instream); } unblock_input (); diff --git a/src/minibuf.c b/src/minibuf.c index 1bbe276776e..835992fa79d 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -20,7 +20,6 @@ along with GNU Emacs. If not, see . */ #include #include -#include #include @@ -31,6 +30,7 @@ along with GNU Emacs. If not, see . */ #include "frame.h" #include "window.h" #include "keymap.h" +#include "sysstdio.h" #include "systty.h" /* List of buffers for use as minibuffers. @@ -209,15 +209,15 @@ read_minibuf_noninteractive (Lisp_Object map, Lisp_Object initial, suppress_echo_on_tty (STDIN_FILENO); } - fwrite (SDATA (prompt), 1, SBYTES (prompt), stdout); - fflush (stdout); + fwrite_unlocked (SDATA (prompt), 1, SBYTES (prompt), stdout); + fflush_unlocked (stdout); val = Qnil; size = 100; len = 0; line = xmalloc (size); - while ((c = getchar ()) != '\n' && c != '\r') + while ((c = getchar_unlocked ()) != '\n' && c != '\r') { if (c == EOF) { diff --git a/src/print.c b/src/print.c index aaec5b04956..6bf8af9ef93 100644 --- a/src/print.c +++ b/src/print.c @@ -228,7 +228,7 @@ printchar_to_stream (unsigned int ch, FILE *stream) { if (ASCII_CHAR_P (ch)) { - putc (ch, stream); + putc_unlocked (ch, stream); #ifdef WINDOWSNT /* Send the output to a debugger (nothing happens if there isn't one). */ @@ -246,7 +246,7 @@ printchar_to_stream (unsigned int ch, FILE *stream) if (encode_p) encoded_ch = code_convert_string_norecord (encoded_ch, coding_system, true); - fwrite (SSDATA (encoded_ch), 1, SBYTES (encoded_ch), stream); + fwrite_unlocked (SSDATA (encoded_ch), 1, SBYTES (encoded_ch), stream); #ifdef WINDOWSNT if (print_output_debug_flag && stream == stderr) OutputDebugString (SSDATA (encoded_ch)); @@ -298,7 +298,7 @@ printchar (unsigned int ch, Lisp_Object fun) if (DISP_TABLE_P (Vstandard_display_table)) printchar_to_stream (ch, stdout); else - fwrite (str, 1, len, stdout); + fwrite_unlocked (str, 1, len, stdout); noninteractive_need_newline = 1; } else @@ -350,7 +350,7 @@ strout (const char *ptr, ptrdiff_t size, ptrdiff_t size_byte, } } else - fwrite (ptr, 1, size_byte, stdout); + fwrite_unlocked (ptr, 1, size_byte, stdout); noninteractive_need_newline = 1; } @@ -801,7 +801,7 @@ append to existing target file. */) report_file_error ("Cannot open debugging output stream", file); } - fflush (stderr); + fflush_unlocked (stderr); if (dup2 (fd, STDERR_FILENO) < 0) report_file_error ("dup2", file); if (fd != stderr_dup) diff --git a/src/sysdep.c b/src/sysdep.c index 70f4a9dd7ea..b52236769e0 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -1408,7 +1408,7 @@ reset_sys_modes (struct tty_display_info *tty_out) { if (noninteractive) { - fflush (stdout); + fflush_unlocked (stdout); return; } if (!tty_out->term_initted) @@ -1428,17 +1428,14 @@ reset_sys_modes (struct tty_display_info *tty_out) } else { /* have to do it the hard way */ - int i; tty_turn_off_insert (tty_out); - for (i = cursorX (tty_out); i < FrameCols (tty_out) - 1; i++) - { - fputc (' ', tty_out->output); - } + for (int i = cursorX (tty_out); i < FrameCols (tty_out) - 1; i++) + fputc_unlocked (' ', tty_out->output); } cmgoto (tty_out, FrameRows (tty_out) - 1, 0); - fflush (tty_out->output); + fflush_unlocked (tty_out->output); if (tty_out->terminal->reset_terminal_modes_hook) tty_out->terminal->reset_terminal_modes_hook (tty_out->terminal); @@ -3079,7 +3076,7 @@ procfs_ttyname (int rdev) char minor[25]; /* 2 32-bit numbers + dash */ char *endp; - for (; !feof (fdev) && !ferror (fdev); name[0] = 0) + for (; !feof_unlocked (fdev) && !ferror_unlocked (fdev); name[0] = 0) { if (fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) >= 3 && major == MAJOR (rdev)) @@ -3129,7 +3126,7 @@ procfs_get_total_memory (void) break; case 0: - while ((c = getc (fmem)) != EOF && c != '\n') + while ((c = getc_unlocked (fmem)) != EOF && c != '\n') continue; done = c == EOF; break; diff --git a/src/sysstdio.h b/src/sysstdio.h index 45ee33f5580..7fbcefcdad9 100644 --- a/src/sysstdio.h +++ b/src/sysstdio.h @@ -33,4 +33,45 @@ extern FILE *emacs_fopen (char const *, char const *); # define FOPEN_TEXT "" #endif +/* These are compatible with unlocked-io.h, if both files are included. */ +#if !HAVE_DECL_CLEARERR_UNLOCKED +# define clearerr_unlocked(x) clearerr (x) +#endif +#if !HAVE_DECL_FEOF_UNLOCKED +# define feof_unlocked(x) feof (x) +#endif +#if !HAVE_DECL_FERROR_UNLOCKED +# define ferror_unlocked(x) ferror (x) +#endif +#if !HAVE_DECL_FFLUSH_UNLOCKED +# define fflush_unlocked(x) fflush (x) +#endif +#if !HAVE_DECL_FGETS_UNLOCKED +# define fgets_unlocked(x,y,z) fgets (x,y,z) +#endif +#if !HAVE_DECL_FPUTC_UNLOCKED +# define fputc_unlocked(x,y) fputc (x,y) +#endif +#if !HAVE_DECL_FPUTS_UNLOCKED +# define fputs_unlocked(x,y) fputs (x,y) +#endif +#if !HAVE_DECL_FREAD_UNLOCKED +# define fread_unlocked(w,x,y,z) fread (w,x,y,z) +#endif +#if !HAVE_DECL_FWRITE_UNLOCKED +# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z) +#endif +#if !HAVE_DECL_GETC_UNLOCKED +# define getc_unlocked(x) getc (x) +#endif +#if !HAVE_DECL_GETCHAR_UNLOCKED +# define getchar_unlocked() getchar () +#endif +#if !HAVE_DECL_PUTC_UNLOCKED +# define putc_unlocked(x,y) putc (x,y) +#endif +#if !HAVE_DECL_PUTCHAR_UNLOCKED +# define putchar_unlocked(x) putchar (x) +#endif + #endif /* EMACS_SYSSTDIO_H */ diff --git a/src/term.c b/src/term.c index 8770aff8a92..3d7f4ada0b9 100644 --- a/src/term.c +++ b/src/term.c @@ -22,7 +22,6 @@ along with GNU Emacs. If not, see . */ #include #include #include -#include #include #include #include @@ -45,6 +44,7 @@ along with GNU Emacs. If not, see . */ #include "keymap.h" #include "blockinput.h" #include "syssignal.h" +#include "sysstdio.h" #ifdef MSDOS #include "msdos.h" static int been_here = -1; @@ -146,7 +146,7 @@ tty_ring_bell (struct frame *f) OUTPUT (tty, (tty->TS_visible_bell && visible_bell ? tty->TS_visible_bell : tty->TS_bell)); - fflush (tty->output); + fflush_unlocked (tty->output); } } @@ -167,9 +167,10 @@ tty_send_additional_strings (struct terminal *terminal, Lisp_Object sym) Lisp_Object string = XCAR (extra_codes); if (STRINGP (string)) { - fwrite (SDATA (string), 1, SBYTES (string), tty->output); + fwrite_unlocked (SDATA (string), 1, SBYTES (string), tty->output); if (tty->termscript) - fwrite (SDATA (string), 1, SBYTES (string), tty->termscript); + fwrite_unlocked (SDATA (string), 1, SBYTES (string), + tty->termscript); } } } @@ -197,7 +198,7 @@ tty_set_terminal_modes (struct terminal *terminal) OUTPUT_IF (tty, tty->TS_keypad_mode); losecursor (tty); tty_send_additional_strings (terminal, Qtty_mode_set_strings); - fflush (tty->output); + fflush_unlocked (tty->output); } } @@ -220,7 +221,7 @@ tty_reset_terminal_modes (struct terminal *terminal) /* Output raw CR so kernel can track the cursor hpos. */ current_tty = tty; cmputc ('\r'); - fflush (tty->output); + fflush_unlocked (tty->output); } } @@ -235,7 +236,7 @@ tty_update_end (struct frame *f) tty_show_cursor (tty); tty_turn_off_insert (tty); tty_background_highlight (tty); - fflush (tty->output); + fflush_unlocked (tty->output); } /* The implementation of set_terminal_window for termcap frames. */ @@ -497,8 +498,8 @@ tty_clear_end_of_line (struct frame *f, int first_unused_hpos) for (i = curX (tty); i < first_unused_hpos; i++) { if (tty->termscript) - fputc (' ', tty->termscript); - fputc (' ', tty->output); + fputc_unlocked (' ', tty->termscript); + fputc_unlocked (' ', tty->output); } cmplus (tty, first_unused_hpos - curX (tty)); } @@ -771,11 +772,11 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len) if (coding->produced > 0) { block_input (); - fwrite (conversion_buffer, 1, coding->produced, tty->output); - if (ferror (tty->output)) - clearerr (tty->output); + fwrite_unlocked (conversion_buffer, 1, coding->produced, tty->output); + clearerr_unlocked (tty->output); if (tty->termscript) - fwrite (conversion_buffer, 1, coding->produced, tty->termscript); + fwrite_unlocked (conversion_buffer, 1, coding->produced, + tty->termscript); unblock_input (); } string += n; @@ -832,11 +833,11 @@ tty_write_glyphs_with_face (register struct frame *f, register struct glyph *str if (coding->produced > 0) { block_input (); - fwrite (conversion_buffer, 1, coding->produced, tty->output); - if (ferror (tty->output)) - clearerr (tty->output); + fwrite_unlocked (conversion_buffer, 1, coding->produced, tty->output); + clearerr_unlocked (tty->output); if (tty->termscript) - fwrite (conversion_buffer, 1, coding->produced, tty->termscript); + fwrite_unlocked (conversion_buffer, 1, coding->produced, + tty->termscript); unblock_input (); } @@ -918,11 +919,11 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len) if (coding->produced > 0) { block_input (); - fwrite (conversion_buffer, 1, coding->produced, tty->output); - if (ferror (tty->output)) - clearerr (tty->output); + fwrite_unlocked (conversion_buffer, 1, coding->produced, tty->output); + clearerr_unlocked (tty->output); if (tty->termscript) - fwrite (conversion_buffer, 1, coding->produced, tty->termscript); + fwrite_unlocked (conversion_buffer, 1, coding->produced, + tty->termscript); unblock_input (); } @@ -3327,7 +3328,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx, which calls tty_show_cursor. Re-hide it, so it doesn't show through the menus. */ tty_hide_cursor (tty); - fflush (tty->output); + fflush_unlocked (tty->output); } sf->mouse_moved = 0; @@ -3335,7 +3336,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx, while (statecount--) free_saved_screen (state[statecount].screen_behind); tty_show_cursor (tty); /* Turn cursor back on. */ - fflush (tty->output); + fflush_unlocked (tty->output); /* Clean up any mouse events that are waiting inside Emacs event queue. These events are likely to be generated before the menu was even diff --git a/src/xfaces.c b/src/xfaces.c index 4714b7b3cb8..86bb9b0b496 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -6232,7 +6232,7 @@ where R,G,B are numbers between 0 and 255 and name is an arbitrary string. */) int red, green, blue; int num; - while (fgets (buf, sizeof (buf), fp) != NULL) { + while (fgets_unlocked (buf, sizeof (buf), fp) != NULL) { if (sscanf (buf, "%d %d %d %n", &red, &green, &blue, &num) == 3) { #ifdef HAVE_NTGUI From dfe73cb06f1dff052aff0abe51ced3b097b06340 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 22 Jun 2017 13:19:13 -0700 Subject: [PATCH 6/6] Remove getc_unlocked configure-time check * configure.ac (getc_unlocked): Remove check, as unlocked-io now does this for us. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 65c5f9268ad..ef61107b025 100644 --- a/configure.ac +++ b/configure.ac @@ -4240,7 +4240,7 @@ AC_CHECK_HEADERS(valgrind/valgrind.h) AC_CHECK_MEMBERS([struct unipair.unicode], [], [], [[#include ]]) -AC_CHECK_FUNCS_ONCE([getc_unlocked sbrk]) +AC_CHECK_FUNCS_ONCE([sbrk]) ok_so_far=yes AC_CHECK_FUNC(socket, , ok_so_far=no)