From: Paul Eggert Date: Wed, 16 Jul 2025 16:47:30 +0000 (-0700) Subject: Port insert-file-contents dir behavior to Unix X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=dd4a1bd4e12507c454eeb7320189c802689375df;p=emacs.git 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. (cherry picked from commit 8a1d368b6241d999668086fed3c20f634b9fb4d3) --- diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index 494eb6461b5..742b37d57f4 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi @@ -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 diff --git a/src/fileio.c b/src/fileio.c index d69cc3d4ad3..e20249379e7 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -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);