From 94344d130c2c2db90bcc47e12870d1d58f020ecf Mon Sep 17 00:00:00 2001 From: Philipp Stephani Date: Sun, 10 Jan 2021 22:28:31 +0100 Subject: [PATCH] Add functions to open a file without quitting. In some situations, e.g. when the Lisp machinery isn't available, we can't quit. Don't check the quit flags in such situations, in case they contain garbage. * src/sysdep.c (emacs_open_noquit, emacs_openat_noquit): New variants of 'emacs_open' and 'emacs_openat' that don't check the quit flags. * src/emacs.c (main, Fdaemon_initialized): * src/pdumper.c (pdumper_load): * src/w32term.c (w32_initialize): * src/buffer.c (mmap_init): * src/callproc.c (emacs_spawn): Use them where we can't quit. --- src/buffer.c | 2 +- src/callproc.c | 2 +- src/emacs.c | 4 ++-- src/lisp.h | 1 + src/pdumper.c | 2 +- src/sysdep.c | 22 ++++++++++++++++++++++ src/w32term.c | 3 ++- 7 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/buffer.c b/src/buffer.c index 71ad5edd527..80c799e719b 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -4785,7 +4785,7 @@ mmap_init (void) if (mmap_fd <= 0) { /* No anonymous mmap -- we need the file descriptor. */ - mmap_fd = emacs_open ("/dev/zero", O_RDONLY, 0); + mmap_fd = emacs_open_noquit ("/dev/zero", O_RDONLY, 0); if (mmap_fd == -1) fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno)); } diff --git a/src/callproc.c b/src/callproc.c index 1da315bef18..cb72b070b7b 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -1336,7 +1336,7 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err, would work? */ if (std_in >= 0) emacs_close (std_in); - std_out = std_in = emacs_open (pty, O_RDWR, 0); + std_out = std_in = emacs_open_noquit (pty, O_RDWR, 0); if (std_in < 0) { diff --git a/src/emacs.c b/src/emacs.c index 69d10821fae..77114271b27 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -1275,7 +1275,7 @@ main (int argc, char **argv) { emacs_close (STDIN_FILENO); emacs_close (STDOUT_FILENO); - int result = emacs_open (term, O_RDWR, 0); + int result = emacs_open_noquit (term, O_RDWR, 0); if (result != STDIN_FILENO || (fcntl (STDIN_FILENO, F_DUPFD_CLOEXEC, STDOUT_FILENO) != STDOUT_FILENO)) @@ -2847,7 +2847,7 @@ from the parent process and its tty file descriptors. */) int nfd; /* Get rid of stdin, stdout and stderr. */ - nfd = emacs_open ("/dev/null", O_RDWR, 0); + nfd = emacs_open_noquit ("/dev/null", O_RDWR, 0); err |= nfd < 0; err |= dup2 (nfd, STDIN_FILENO) < 0; err |= dup2 (nfd, STDOUT_FILENO) < 0; diff --git a/src/lisp.h b/src/lisp.h index 86be25852a6..9d8dbbd629f 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4577,6 +4577,7 @@ extern AVOID emacs_abort (void) NO_INLINE; extern int emacs_fstatat (int, char const *, void *, int); extern int emacs_openat (int, char const *, int, int); extern int emacs_open (const char *, int, int); +extern int emacs_open_noquit (const char *, int, int); extern int emacs_pipe (int[2]); extern int emacs_close (int); extern ptrdiff_t emacs_read (int, void *, ptrdiff_t); diff --git a/src/pdumper.c b/src/pdumper.c index 116cc28dbba..c1388ebbb37 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -5273,7 +5273,7 @@ pdumper_load (const char *dump_filename) eassert (!dump_loaded_p ()); int err; - int dump_fd = emacs_open (dump_filename, O_RDONLY, 0); + int dump_fd = emacs_open_noquit (dump_filename, O_RDONLY, 0); if (dump_fd < 0) { err = (errno == ENOENT || errno == ENOTDIR diff --git a/src/sysdep.c b/src/sysdep.c index a49f1775ebd..941b4e2fa24 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -2320,6 +2320,28 @@ emacs_open (char const *file, int oflags, int mode) return emacs_openat (AT_FDCWD, file, oflags, mode); } +/* Same as above, but doesn't allow the user to quit. */ + +static int +emacs_openat_noquit (int dirfd, const char *file, int oflags, + int mode) +{ + int fd; + if (! (oflags & O_TEXT)) + oflags |= O_BINARY; + oflags |= O_CLOEXEC; + do + fd = openat (dirfd, file, oflags, mode); + while (fd < 0 && errno == EINTR); + return fd; +} + +int +emacs_open_noquit (char const *file, int oflags, int mode) +{ + return emacs_openat_noquit (AT_FDCWD, file, oflags, mode); +} + /* Open FILE as a stream for Emacs use, with mode MODE. Act like emacs_open with respect to threads, signals, and quits. */ diff --git a/src/w32term.c b/src/w32term.c index e5a8a823b48..109aa58d732 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -7507,7 +7507,8 @@ w32_initialize (void) } #ifdef CYGWIN - if ((w32_message_fd = emacs_open ("/dev/windows", O_RDWR, 0)) == -1) + if ((w32_message_fd = emacs_open_noquit ("/dev/windows", O_RDWR, 0)) + == -1) fatal ("opening /dev/windows: %s", strerror (errno)); #endif /* CYGWIN */ -- 2.39.5