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.
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
'
#include <config.h>
#include <stddef.h>
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <getopt.h>
+#include <flexmember.h>
+#include <min-max.h>
+#include <unlocked-io.h>
+
/* The SunOS compiler doesn't have SEEK_END. */
#ifndef SEEK_END
#define SEEK_END 2
#endif
-#include <flexmember.h>
-#include <min-max.h>
-
/* Files are read in chunks of this number of bytes. */
enum { READ_CHUNK_SIZE = 100 * 1024 };
#include <stdarg.h>
#include <ctype.h>
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <signal.h>
#include <errno.h>
+#include <unlocked-io.h>
+
#ifndef VERSION
#define VERSION "unspecified"
#endif
#include <errno.h>
#include <fcntl.h>
#include <binary-io.h>
+#include <unlocked-io.h>
#include <c-ctype.h>
#include <c-strcase.h>
#include <config.h>
#include <inttypes.h>
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <binary-io.h>
+#include <unlocked-io.h>
static char *progname;
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <binary-io.h>
+#include <intprops.h>
+#include <min-max.h>
+#include <unlocked-io.h>
+
#ifdef WINDOWSNT
/* Defined to be sys_fopen in ms-w32.h, but only #ifdef emacs, so this
is really just insurance. */
#include <direct.h>
#endif /* WINDOWSNT */
-#include <binary-io.h>
-#include <intprops.h>
-#include <min-max.h>
-
#ifdef DOS_NT
/* Defined to be sys_chdir in ms-w32.h, but only #ifdef emacs, so this
is really just insurance.
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
-#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
#include <fcntl.h>
#include <signal.h>
#include <string.h>
+
+#include <unlocked-io.h>
+
#include "syswait.h"
#ifdef MAIL_USE_POP
#include "pop.h"
#include <config.h>
#include <inttypes.h>
-#include <stdio.h>
#include <stdlib.h>
#include <intprops.h>
#include <systime.h>
+#include <unlocked-io.h>
static struct timespec TV1;
static int watch_not_started = 1; /* flag */
#include <limits.h>
#include <string.h>
#include <stdlib.h>
-#include <stdio.h>
#include <time.h>
#include <pwd.h>
#include <ctype.h>
#include <sys/stat.h>
#include <getopt.h>
+#include <unlocked-io.h>
+
#ifdef WINDOWSNT
#include "ntlib.h"
#endif
# 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
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))
--- /dev/null
+/* 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 <http://www.gnu.org/licenses/>. */
+
+/* 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 <stdio.h>
+
+# 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 */
# 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:
gl_TIMER_TIME
gl_TIMESPEC
gl_UNISTD_H
+ gl_FUNC_GLIBC_UNLOCKED_IO
gl_UTIMENS
AC_C_VARARRAYS
gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b=false
lib/u64.h
lib/unistd.c
lib/unistd.in.h
+ lib/unlocked-io.h
lib/utimens.c
lib/utimens.h
lib/verify.h
m4/timespec.m4
m4/tm_gmtoff.m4
m4/unistd_h.m4
+ m4/unlocked-io.m4
m4/utimens.m4
m4/utimes.m4
m4/vararrays.m4
--- /dev/null
+# 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 <stdio.h> 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])
+])
#include <config.h>
#include <errno.h>
-#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include "charset.h"
#include "coding.h"
#include "buffer.h"
+#include "sysstdio.h"
/*** GENERAL NOTES on CODED CHARACTER SETS (CHARSETS) ***
#define GET_TEMP_CHARSET_WORK_DECODER(CODE) \
(temp_charset_work->table.decoder[(CODE)])
-
-#ifndef HAVE_GETC_UNLOCKED
-#define getc_unlocked getc
-#endif
\f
/* Set to 1 to warn that a charset map is loaded and thus a buffer
#include <config.h>
-#include <stdio.h>
#include "lisp.h"
#include "cm.h"
+#include "sysstdio.h"
#include "termchar.h"
#include "tparam.h"
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;
}
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)++;
}
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. */
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
ptrdiff_t outq = __fpending (display_output);
if (outq > 900
|| (outq > 20 && ((i - 1) % preempt_count == 0)))
- fflush (display_output);
+ fflush_unlocked (display_output);
}
}
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;
}
if (!NILP (arg))
{
if (noninteractive)
- putchar (07);
+ putchar_unlocked (07);
else
ring_bell (XFRAME (selected_frame));
}
bitch_at_user (void)
{
if (noninteractive)
- putchar (07);
+ putchar_unlocked (07);
else if (!INTERACTIVE) /* Stop executing a keyboard macro. */
{
const char *msg
#include <errno.h>
#include <fcntl.h>
-#include <stdio.h>
#include <stdlib.h>
#include <sys/file.h>
#define MAIN_PROGRAM
#include "lisp.h"
+#include "sysstdio.h"
#ifdef WINDOWSNT
#include <fcntl.h>
}
#endif /* HAVE_SETRLIMIT and RLIMIT_STACK and not CYGWIN */
- clearerr (stdin);
+ clearerr_unlocked (stdin);
emacs_backtrace (-1);
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);
}
}
#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
{
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 ();
}
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;
}
#include <config.h>
#include <fcntl.h>
-#include <stdio.h>
#include <unistd.h>
/* Include this before including <setjmp.h> to work around bugs with
#include "buffer.h"
#include "dispextern.h"
#include "blockinput.h"
+#include "sysstdio.h"
#include "systime.h"
#include <epaths.h>
#include "coding.h"
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
{
{
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");
}
}
/* 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);
{
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
#include "intervals.h"
#include "keymap.h"
#include "blockinput.h"
+#include "sysstdio.h"
#include "systime.h"
#include "atimer.h"
#include "process.h"
if (INTEGERP (c))
{
if (XUINT (c) < 0x100)
- putc (XUINT (c), dribble);
+ putc_unlocked (XUINT (c), dribble);
else
fprintf (dribble, " 0x%"pI"x", XUINT (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 ();
}
}
detaching from the terminal. */
|| (IS_DAEMON && DAEMON_RUNNING))
{
- int c = getchar ();
+ int c = getchar_unlocked ();
XSETINT (obj, c);
*kbp = current_kboard;
return obj;
sigemptyset (&blocked);
sigaddset (&blocked, SIGINT);
pthread_sigmask (SIG_BLOCK, &blocked, 0);
- fflush (stdout);
+ fflush_unlocked (stdout);
}
reset_all_sys_modes ();
#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
}
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 ();
#include <config.h>
#include <errno.h>
-#include <stdio.h>
#include <binary-io.h>
#include "frame.h"
#include "window.h"
#include "keymap.h"
+#include "sysstdio.h"
#include "systty.h"
/* List of buffers for use as minibuffers.
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)
{
{
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). */
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));
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
}
}
else
- fwrite (ptr, 1, size_byte, stdout);
+ fwrite_unlocked (ptr, 1, size_byte, stdout);
noninteractive_need_newline = 1;
}
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)
{
if (noninteractive)
{
- fflush (stdout);
+ fflush_unlocked (stdout);
return;
}
if (!tty_out->term_initted)
}
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);
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))
break;
case 0:
- while ((c = getc (fmem)) != EOF && c != '\n')
+ while ((c = getc_unlocked (fmem)) != EOF && c != '\n')
continue;
done = c == EOF;
break;
# 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 */
#include <config.h>
#include <errno.h>
#include <fcntl.h>
-#include <stdio.h>
#include <stdlib.h>
#include <sys/file.h>
#include <sys/time.h>
#include "keymap.h"
#include "blockinput.h"
#include "syssignal.h"
+#include "sysstdio.h"
#ifdef MSDOS
#include "msdos.h"
static int been_here = -1;
OUTPUT (tty, (tty->TS_visible_bell && visible_bell
? tty->TS_visible_bell
: tty->TS_bell));
- fflush (tty->output);
+ fflush_unlocked (tty->output);
}
}
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);
}
}
}
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);
}
}
/* Output raw CR so kernel can track the cursor hpos. */
current_tty = tty;
cmputc ('\r');
- fflush (tty->output);
+ fflush_unlocked (tty->output);
}
}
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. */
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));
}
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;
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 ();
}
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 ();
}
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;
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
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