summaryrefslogtreecommitdiff
path: root/src/doc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/doc.c')
-rw-r--r--src/doc.c41
1 files changed, 23 insertions, 18 deletions
diff --git a/src/doc.c b/src/doc.c
index 3c5a682c001..009616f4f87 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -21,6 +21,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
+#include <errno.h>
#include <sys/types.h>
#include <sys/file.h> /* Must be after sys/types.h for USG. */
#include <fcntl.h>
@@ -84,6 +85,7 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
int offset;
EMACS_INT position;
Lisp_Object file, tem, pos;
+ ptrdiff_t count;
USE_SAFE_ALLOCA;
if (INTEGERP (filepos))
@@ -143,9 +145,14 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
}
#endif
if (fd < 0)
- return concat3 (build_string ("Cannot open doc string file \""),
- file, build_string ("\"\n"));
+ {
+ SAFE_FREE ();
+ return concat3 (build_string ("Cannot open doc string file \""),
+ file, build_string ("\"\n"));
+ }
}
+ count = SPECPDL_INDEX ();
+ record_unwind_protect_int (close_file_unwind, fd);
/* Seek only to beginning of disk block. */
/* Make sure we read at least 1024 bytes before `position'
@@ -153,13 +160,8 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
offset = min (position, max (1024, position % (8 * 1024)));
if (TYPE_MAXIMUM (off_t) < position
|| lseek (fd, position - offset, 0) < 0)
- {
- emacs_close (fd);
- error ("Position %"pI"d out of range in doc string file \"%s\"",
- position, name);
- }
-
- SAFE_FREE ();
+ error ("Position %"pI"d out of range in doc string file \"%s\"",
+ position, name);
/* Read the doc string into get_doc_string_buffer.
P points beyond the data just read. */
@@ -189,10 +191,7 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
space_left = 1024 * 8;
nread = emacs_read (fd, p, space_left);
if (nread < 0)
- {
- emacs_close (fd);
- error ("Read error on documentation file");
- }
+ report_file_error ("Read error on documentation file", file);
p[nread] = 0;
if (!nread)
break;
@@ -208,7 +207,8 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
}
p += nread;
}
- emacs_close (fd);
+ unbind_to (count, Qnil);
+ SAFE_FREE ();
/* Sanity checking. */
if (CONSP (filepos))
@@ -573,6 +573,7 @@ the same file name is found in the `doc-directory'. */)
Lisp_Object sym;
char *p, *name;
bool skip_file = 0;
+ ptrdiff_t count;
CHECK_STRING (filename);
@@ -609,8 +610,13 @@ the same file name is found in the `doc-directory'. */)
fd = emacs_open (name, O_RDONLY, 0);
if (fd < 0)
- report_file_error ("Opening doc string file",
- Fcons (build_string (name), Qnil));
+ {
+ int open_errno = errno;
+ report_file_errno ("Opening doc string file", build_string (name),
+ open_errno);
+ }
+ count = SPECPDL_INDEX ();
+ record_unwind_protect_int (close_file_unwind, fd);
Vdoc_file_name = filename;
filled = 0;
pos = 0;
@@ -688,8 +694,7 @@ the same file name is found in the `doc-directory'. */)
filled -= end - buf;
memmove (buf, end, filled);
}
- emacs_close (fd);
- return Qnil;
+ return unbind_to (count, Qnil);
}
DEFUN ("substitute-command-keys", Fsubstitute_command_keys,