Port insert-file-contents dir behavior to Unix

* src/fileio.c (Finsert_file_contents): Port better to traditional
Unix platforms like Solaris, where in some cases 'read' can
succeed on directories.
This commit is contained in:
Paul Eggert 2025-07-16 09:47:30 -07:00
parent b282cb98e4
commit 8a1d368b62
2 changed files with 17 additions and 4 deletions

View file

@ -536,7 +536,8 @@ Name}).
This function inserts the contents of file @var{filename} into the
current buffer after point. It returns a list of the absolute file name
and the length of the data inserted. An error is signaled if
@var{filename} is not the name of a file that can be read.
@var{filename} does not name a file that can be read, or names a
directory.
This function checks the file contents against the defined file
formats, and converts the file contents if appropriate and also calls

View file

@ -4038,9 +4038,9 @@ DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents,
doc: /* Insert contents of file FILENAME after point.
Returns list of absolute file name and number of characters inserted.
If second argument VISIT is non-nil, the buffer's visited filename and
last save file modtime are set, and it is marked unmodified. If
visiting and the file does not exist, visiting is completed before the
error is signaled.
last save file modtime are set, and it is marked unmodified. Signal an
error if FILENAME cannot be read or is a directory. If visiting and the
file does not exist, visiting is completed before the error is signaled.
The optional third and fourth arguments BEG and END specify what portion
of the file to insert. These arguments count bytes in the file, not
@ -4186,6 +4186,18 @@ by calling `format-decode', which see. */)
struct stat st;
if (emacs_fd_fstat (fd, &st) < 0)
report_file_error ("Input file status", orig_filename);
/* For backwards compatibility to traditional Unix,
POSIX allows the 'read' syscall to succeed on directories.
However, we want to fail, to be consistent across platforms
and to let callers rely on this function failing on directories.
There is no need to check on platforms where it is known that the
'read' syscall always fails on a directory. */
#if ! (defined GNU_LINUX || defined __ANDROID__)
if (S_ISDIR (st.st_mode))
report_file_errno ("Read error", orig_filename, EISDIR);
#endif
regular = S_ISREG (st.st_mode) != 0;
bool memory_object = S_TYPEISSHM (&st) || S_TYPEISTMO (&st);