aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2013-07-12 10:30:48 -0700
committerPaul Eggert2013-07-12 10:30:48 -0700
commita773ed9ac83b950cb2a934e9d54e1880f44bd350 (patch)
treeaa859e605867e85ae4fdee5401deddb18e0a630a /src
parent7e649856bce883738622cc3533ad808c6ea1a73f (diff)
downloademacs-a773ed9ac83b950cb2a934e9d54e1880f44bd350.tar.gz
emacs-a773ed9ac83b950cb2a934e9d54e1880f44bd350.zip
Clean up errno reporting and fix some errno-reporting bugs.
* callproc.c (Fcall_process): * fileio.c (Fcopy_file, Finsert_file_contents, Fwrite_region): * process.c (create_process, Fmake_network_process): * unexaix.c (report_error): * unexcoff.c (report_error): Be more careful about reporting the errno of failed operations. The code previously reported the wrong errno sometimes. Also, prefer report_file_errno to setting errno + report_file_error. (Fcall_process): Look at openp return value rather than at path, as that's a bit faster and clearer when there's a numeric predicate. * fileio.c (report_file_errno): New function, with most of the old contents of report_file_error. (report_file_error): Use it. (Ffile_exists_p, Ffile_accessible_directory_p): Set errno to 0 when it is junk. * fileio.c (Faccess_file): * image.c (x_create_bitmap_from_file): Use faccessat rather than opening the file, to avoid the hassle of having a file descriptor open. * lisp.h (report_file_errno): New decl. * lread.c (Flocate_file_internal): File descriptor 0 is valid, too.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog23
-rw-r--r--src/callproc.c74
-rw-r--r--src/fileio.c81
-rw-r--r--src/image.c5
-rw-r--r--src/lisp.h1
-rw-r--r--src/lread.c2
-rw-r--r--src/process.c26
-rw-r--r--src/unexaix.c9
-rw-r--r--src/unexcoff.c3
9 files changed, 120 insertions, 104 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index dfc74d7bb39..6e3a82c7c13 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,28 @@
12013-07-12 Paul Eggert <eggert@cs.ucla.edu> 12013-07-12 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 Clean up errno reporting and fix some errno-reporting bugs.
4 * callproc.c (Fcall_process):
5 * fileio.c (Fcopy_file, Finsert_file_contents, Fwrite_region):
6 * process.c (create_process, Fmake_network_process):
7 * unexaix.c (report_error):
8 * unexcoff.c (report_error):
9 Be more careful about reporting the errno of failed operations.
10 The code previously reported the wrong errno sometimes.
11 Also, prefer report_file_errno to setting errno + report_file_error.
12 (Fcall_process): Look at openp return value rather than at path,
13 as that's a bit faster and clearer when there's a numeric predicate.
14 * fileio.c (report_file_errno): New function, with most of the
15 old contents of report_file_error.
16 (report_file_error): Use it.
17 (Ffile_exists_p, Ffile_accessible_directory_p):
18 Set errno to 0 when it is junk.
19 * fileio.c (Faccess_file):
20 * image.c (x_create_bitmap_from_file):
21 Use faccessat rather than opening the file, to avoid the hassle of
22 having a file descriptor open.
23 * lisp.h (report_file_errno): New decl.
24 * lread.c (Flocate_file_internal): File descriptor 0 is valid, too.
25
3 Minor EBADF fixes. 26 Minor EBADF fixes.
4 * process.c (create_process, wait_reading_process_output) [AIX]: 27 * process.c (create_process, wait_reading_process_output) [AIX]:
5 Remove obsolete SIGHUP-related code, as Emacs no longer disables 28 Remove obsolete SIGHUP-related code, as Emacs no longer disables
diff --git a/src/callproc.c b/src/callproc.c
index ac9477bff10..30f9dc58d46 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -419,9 +419,10 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
419 default_output_mode); 419 default_output_mode);
420 if (fd_output < 0) 420 if (fd_output < 0)
421 { 421 {
422 int open_errno = errno;
422 output_file = DECODE_FILE (output_file); 423 output_file = DECODE_FILE (output_file);
423 report_file_error ("Opening process output file", 424 report_file_errno ("Opening process output file",
424 Fcons (output_file, Qnil)); 425 Fcons (output_file, Qnil), open_errno);
425 } 426 }
426 if (STRINGP (error_file) || NILP (error_file)) 427 if (STRINGP (error_file) || NILP (error_file))
427 output_to_buffer = 0; 428 output_to_buffer = 0;
@@ -430,18 +431,19 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
430 /* Search for program; barf if not found. */ 431 /* Search for program; barf if not found. */
431 { 432 {
432 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 433 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
434 int ok;
433 435
434 GCPRO4 (infile, buffer, current_dir, error_file); 436 GCPRO4 (infile, buffer, current_dir, error_file);
435 openp (Vexec_path, args[0], Vexec_suffixes, &path, make_number (X_OK)); 437 ok = openp (Vexec_path, args[0], Vexec_suffixes, &path, make_number (X_OK));
436 UNGCPRO; 438 UNGCPRO;
439 if (ok < 0)
440 {
441 int openp_errno = errno;
442 emacs_close (filefd);
443 report_file_errno ("Searching for program",
444 Fcons (args[0], Qnil), openp_errno);
445 }
437 } 446 }
438 if (NILP (path))
439 {
440 int openp_errno = errno;
441 emacs_close (filefd);
442 errno = openp_errno;
443 report_file_error ("Searching for program", Fcons (args[0], Qnil));
444 }
445 447
446 /* If program file name starts with /: for quoting a magic name, 448 /* If program file name starts with /: for quoting a magic name,
447 discard that. */ 449 discard that. */
@@ -499,11 +501,13 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
499 mktemp (tempfile); 501 mktemp (tempfile);
500 outfilefd = emacs_open (tempfile, O_WRONLY | O_CREAT | O_TRUNC, 502 outfilefd = emacs_open (tempfile, O_WRONLY | O_CREAT | O_TRUNC,
501 S_IREAD | S_IWRITE); 503 S_IREAD | S_IWRITE);
502 if (outfilefd < 0) { 504 if (outfilefd < 0)
503 emacs_close (filefd); 505 {
504 report_file_error ("Opening process output file", 506 int open_errno = errno;
505 Fcons (build_string (tempfile), Qnil)); 507 emacs_close (filefd);
506 } 508 report_file_errno ("Opening process output file",
509 Fcons (build_string (tempfile), Qnil), open_errno);
510 }
507 } 511 }
508 else 512 else
509 outfilefd = fd_output; 513 outfilefd = fd_output;
@@ -524,8 +528,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
524 { 528 {
525 int pipe_errno = errno; 529 int pipe_errno = errno;
526 emacs_close (filefd); 530 emacs_close (filefd);
527 errno = pipe_errno; 531 report_file_errno ("Creating process pipe", Qnil, pipe_errno);
528 report_file_error ("Creating process pipe", Qnil);
529 } 532 }
530 fd0 = fd[0]; 533 fd0 = fd[0];
531 fd1 = fd[1]; 534 fd1 = fd[1];
@@ -547,6 +550,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
547 550
548 if (fd_error < 0) 551 if (fd_error < 0)
549 { 552 {
553 int open_errno = errno;
550 emacs_close (filefd); 554 emacs_close (filefd);
551 if (fd0 != filefd) 555 if (fd0 != filefd)
552 emacs_close (fd0); 556 emacs_close (fd0);
@@ -559,7 +563,8 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
559 error_file = build_string (NULL_DEVICE); 563 error_file = build_string (NULL_DEVICE);
560 else if (STRINGP (error_file)) 564 else if (STRINGP (error_file))
561 error_file = DECODE_FILE (error_file); 565 error_file = DECODE_FILE (error_file);
562 report_file_error ("Cannot redirect stderr", Fcons (error_file, Qnil)); 566 report_file_errno ("Cannot redirect stderr",
567 Fcons (error_file, Qnil), open_errno);
563 } 568 }
564 569
565#ifdef MSDOS /* MW, July 1993 */ 570#ifdef MSDOS /* MW, July 1993 */
@@ -587,10 +592,12 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
587 fd0 = emacs_open (tempfile, O_RDONLY | O_BINARY, 0); 592 fd0 = emacs_open (tempfile, O_RDONLY | O_BINARY, 0);
588 if (fd0 < 0) 593 if (fd0 < 0)
589 { 594 {
595 int open_errno = errno;
590 unlink (tempfile); 596 unlink (tempfile);
591 emacs_close (filefd); 597 emacs_close (filefd);
592 report_file_error ("Cannot re-open temporary file", 598 report_file_errno ("Cannot re-open temporary file",
593 Fcons (build_string (tempfile), Qnil)); 599 Fcons (build_string (tempfile), Qnil),
600 open_errno);
594 } 601 }
595 } 602 }
596 else 603 else
@@ -708,10 +715,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
708 } 715 }
709 716
710 if (pid < 0) 717 if (pid < 0)
711 { 718 report_file_errno ("Doing vfork", Qnil, child_errno);
712 errno = child_errno;
713 report_file_error ("Doing vfork", Qnil);
714 }
715 719
716 if (INTEGERP (buffer)) 720 if (INTEGERP (buffer))
717 return unbind_to (count, Qnil); 721 return unbind_to (count, Qnil);
@@ -1039,7 +1043,7 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
1039 1043
1040#if defined HAVE_MKOSTEMP || defined HAVE_MKSTEMP 1044#if defined HAVE_MKOSTEMP || defined HAVE_MKSTEMP
1041 { 1045 {
1042 int fd; 1046 int fd, open_errno;
1043 1047
1044 block_input (); 1048 block_input ();
1045# ifdef HAVE_MKOSTEMP 1049# ifdef HAVE_MKOSTEMP
@@ -1047,23 +1051,19 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
1047# else 1051# else
1048 fd = mkstemp (tempfile); 1052 fd = mkstemp (tempfile);
1049# endif 1053# endif
1054 open_errno = errno;
1050 unblock_input (); 1055 unblock_input ();
1051 if (fd == -1) 1056 if (fd < 0)
1052 report_file_error ("Failed to open temporary file", 1057 report_file_errno ("Failed to open temporary file",
1053 Fcons (build_string (tempfile), Qnil)); 1058 Fcons (build_string (tempfile), Qnil), open_errno);
1054 else 1059 emacs_close (fd);
1055 emacs_close (fd);
1056 } 1060 }
1057#else 1061#else
1058 errno = 0; 1062 errno = EEXIST;
1059 mktemp (tempfile); 1063 mktemp (tempfile);
1060 if (!*tempfile) 1064 if (!*tempfile)
1061 { 1065 report_file_error ("Failed to open temporary file using pattern",
1062 if (!errno) 1066 Fcons (pattern, Qnil));
1063 errno = EEXIST;
1064 report_file_error ("Failed to open temporary file using pattern",
1065 Fcons (pattern, Qnil));
1066 }
1067#endif 1067#endif
1068 1068
1069 filename_string = build_string (tempfile); 1069 filename_string = build_string (tempfile);
diff --git a/src/fileio.c b/src/fileio.c
index cb863410ccf..c3566390130 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -159,11 +159,13 @@ static bool e_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t,
159 struct coding_system *); 159 struct coding_system *);
160 160
161 161
162/* Signal a file-access failure. STRING describes the failure,
163 DATA the file that was involved, and ERRORNO the errno value. */
164
162void 165void
163report_file_error (const char *string, Lisp_Object data) 166report_file_errno (char const *string, Lisp_Object data, int errorno)
164{ 167{
165 Lisp_Object errstring; 168 Lisp_Object errstring;
166 int errorno = errno;
167 char *str; 169 char *str;
168 170
169 synchronize_system_messages_locale (); 171 synchronize_system_messages_locale ();
@@ -196,6 +198,12 @@ report_file_error (const char *string, Lisp_Object data)
196 } 198 }
197} 199}
198 200
201void
202report_file_error (char const *string, Lisp_Object data)
203{
204 report_file_errno (string, data, errno);
205}
206
199Lisp_Object 207Lisp_Object
200close_file_unwind (Lisp_Object fd) 208close_file_unwind (Lisp_Object fd)
201{ 209{
@@ -2019,11 +2027,8 @@ entries (depending on how Emacs was built). */)
2019 { 2027 {
2020 /* CopyFile doesn't set errno when it fails. By far the most 2028 /* CopyFile doesn't set errno when it fails. By far the most
2021 "popular" reason is that the target is read-only. */ 2029 "popular" reason is that the target is read-only. */
2022 if (GetLastError () == 5) 2030 report_file_errno ("Copying file", Fcons (file, Fcons (newname, Qnil)),
2023 errno = EACCES; 2031 GetLastError () == 5 ? EACCES : EPERM);
2024 else
2025 errno = EPERM;
2026 report_file_error ("Copying file", Fcons (file, Fcons (newname, Qnil)));
2027 } 2032 }
2028 /* CopyFile retains the timestamp by default. */ 2033 /* CopyFile retains the timestamp by default. */
2029 else if (NILP (keep_time)) 2034 else if (NILP (keep_time))
@@ -2084,36 +2089,25 @@ entries (depending on how Emacs was built). */)
2084 2089
2085 if (out_st.st_mode != 0 2090 if (out_st.st_mode != 0
2086 && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino) 2091 && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino)
2087 { 2092 report_file_errno ("Input and output files are the same",
2088 errno = 0; 2093 Fcons (file, Fcons (newname, Qnil)), 0);
2089 report_file_error ("Input and output files are the same",
2090 Fcons (file, Fcons (newname, Qnil)));
2091 }
2092 2094
2093 /* We can copy only regular files. */ 2095 /* We can copy only regular files. */
2094 if (!S_ISREG (st.st_mode)) 2096 if (!S_ISREG (st.st_mode))
2095 { 2097 report_file_errno ("Non-regular file", Fcons (file, Qnil),
2096 /* Get a better looking error message. */ 2098 S_ISDIR (st.st_mode) ? EISDIR : EINVAL);
2097 errno = S_ISDIR (st.st_mode) ? EISDIR : EINVAL;
2098 report_file_error ("Non-regular file", Fcons (file, Qnil));
2099 }
2100 2099
2101#ifdef MSDOS
2102 /* System's default file type was set to binary by _fmode in emacs.c. */
2103 ofd = emacs_open (SDATA (encoded_newname),
2104 O_WRONLY | O_TRUNC | O_CREAT
2105 | (NILP (ok_if_already_exists) ? O_EXCL : 0),
2106 S_IREAD | S_IWRITE);
2107#else /* not MSDOS */
2108 { 2100 {
2109 mode_t new_mask = !NILP (preserve_uid_gid) ? 0600 : 0666; 2101#ifndef MSDOS
2110 new_mask &= st.st_mode; 2102 int new_mask = st.st_mode & (!NILP (preserve_uid_gid) ? 0600 : 0666);
2103#else
2104 int new_mask = S_IREAD | S_IWRITE;
2105#endif
2111 ofd = emacs_open (SSDATA (encoded_newname), 2106 ofd = emacs_open (SSDATA (encoded_newname),
2112 (O_WRONLY | O_TRUNC | O_CREAT 2107 (O_WRONLY | O_TRUNC | O_CREAT
2113 | (NILP (ok_if_already_exists) ? O_EXCL : 0)), 2108 | (NILP (ok_if_already_exists) ? O_EXCL : 0)),
2114 new_mask); 2109 new_mask);
2115 } 2110 }
2116#endif /* not MSDOS */
2117 if (ofd < 0) 2111 if (ofd < 0)
2118 report_file_error ("Opening output file", Fcons (newname, Qnil)); 2112 report_file_error ("Opening output file", Fcons (newname, Qnil));
2119 2113
@@ -2609,7 +2603,11 @@ Use `file-symlink-p' to test for such links. */)
2609 call the corresponding file handler. */ 2603 call the corresponding file handler. */
2610 handler = Ffind_file_name_handler (absname, Qfile_exists_p); 2604 handler = Ffind_file_name_handler (absname, Qfile_exists_p);
2611 if (!NILP (handler)) 2605 if (!NILP (handler))
2612 return call2 (handler, Qfile_exists_p, absname); 2606 {
2607 Lisp_Object result = call2 (handler, Qfile_exists_p, absname);
2608 errno = 0;
2609 return result;
2610 }
2613 2611
2614 absname = ENCODE_FILE (absname); 2612 absname = ENCODE_FILE (absname);
2615 2613
@@ -2706,7 +2704,6 @@ If there is no error, returns nil. */)
2706 (Lisp_Object filename, Lisp_Object string) 2704 (Lisp_Object filename, Lisp_Object string)
2707{ 2705{
2708 Lisp_Object handler, encoded_filename, absname; 2706 Lisp_Object handler, encoded_filename, absname;
2709 int fd;
2710 2707
2711 CHECK_STRING (filename); 2708 CHECK_STRING (filename);
2712 absname = Fexpand_file_name (filename, Qnil); 2709 absname = Fexpand_file_name (filename, Qnil);
@@ -2721,10 +2718,8 @@ If there is no error, returns nil. */)
2721 2718
2722 encoded_filename = ENCODE_FILE (absname); 2719 encoded_filename = ENCODE_FILE (absname);
2723 2720
2724 fd = emacs_open (SSDATA (encoded_filename), O_RDONLY, 0); 2721 if (faccessat (AT_FDCWD, SSDATA (encoded_filename), R_OK, AT_EACCESS) != 0)
2725 if (fd < 0)
2726 report_file_error (SSDATA (string), Fcons (filename, Qnil)); 2722 report_file_error (SSDATA (string), Fcons (filename, Qnil));
2727 emacs_close (fd);
2728 2723
2729 return Qnil; 2724 return Qnil;
2730} 2725}
@@ -2833,7 +2828,11 @@ searchable directory. */)
2833 call the corresponding file handler. */ 2828 call the corresponding file handler. */
2834 handler = Ffind_file_name_handler (absname, Qfile_accessible_directory_p); 2829 handler = Ffind_file_name_handler (absname, Qfile_accessible_directory_p);
2835 if (!NILP (handler)) 2830 if (!NILP (handler))
2836 return call2 (handler, Qfile_accessible_directory_p, absname); 2831 {
2832 Lisp_Object r = call2 (handler, Qfile_accessible_directory_p, absname);
2833 errno = 0;
2834 return r;
2835 }
2837 2836
2838 absname = ENCODE_FILE (absname); 2837 absname = ENCODE_FILE (absname);
2839 return file_accessible_directory_p (SSDATA (absname)) ? Qt : Qnil; 2838 return file_accessible_directory_p (SSDATA (absname)) ? Qt : Qnil;
@@ -4575,8 +4574,8 @@ by calling `format-decode', which see. */)
4575 && EMACS_NSECS (current_buffer->modtime) == NONEXISTENT_MODTIME_NSECS) 4574 && EMACS_NSECS (current_buffer->modtime) == NONEXISTENT_MODTIME_NSECS)
4576 { 4575 {
4577 /* If visiting nonexistent file, return nil. */ 4576 /* If visiting nonexistent file, return nil. */
4578 errno = save_errno; 4577 report_file_errno ("Opening input file", Fcons (orig_filename, Qnil),
4579 report_file_error ("Opening input file", Fcons (orig_filename, Qnil)); 4578 save_errno);
4580 } 4579 }
4581 4580
4582 if (read_quit) 4581 if (read_quit)
@@ -4897,13 +4896,13 @@ This calls `write-region-annotate-functions' at the start, and
4897 4896
4898 if (desc < 0) 4897 if (desc < 0)
4899 { 4898 {
4899 int open_errno = errno;
4900#ifdef CLASH_DETECTION 4900#ifdef CLASH_DETECTION
4901 save_errno = errno;
4902 if (!auto_saving) unlock_file (lockname); 4901 if (!auto_saving) unlock_file (lockname);
4903 errno = save_errno;
4904#endif /* CLASH_DETECTION */ 4902#endif /* CLASH_DETECTION */
4905 UNGCPRO; 4903 UNGCPRO;
4906 report_file_error ("Opening output file", Fcons (filename, Qnil)); 4904 report_file_errno ("Opening output file", Fcons (filename, Qnil),
4905 open_errno);
4907 } 4906 }
4908 4907
4909 record_unwind_protect (close_file_unwind, make_number (desc)); 4908 record_unwind_protect (close_file_unwind, make_number (desc));
@@ -4913,13 +4912,13 @@ This calls `write-region-annotate-functions' at the start, and
4913 off_t ret = lseek (desc, offset, SEEK_SET); 4912 off_t ret = lseek (desc, offset, SEEK_SET);
4914 if (ret < 0) 4913 if (ret < 0)
4915 { 4914 {
4915 int lseek_errno = errno;
4916#ifdef CLASH_DETECTION 4916#ifdef CLASH_DETECTION
4917 save_errno = errno;
4918 if (!auto_saving) unlock_file (lockname); 4917 if (!auto_saving) unlock_file (lockname);
4919 errno = save_errno;
4920#endif /* CLASH_DETECTION */ 4918#endif /* CLASH_DETECTION */
4921 UNGCPRO; 4919 UNGCPRO;
4922 report_file_error ("Lseek error", Fcons (filename, Qnil)); 4920 report_file_errno ("Lseek error", Fcons (filename, Qnil),
4921 lseek_errno);
4923 } 4922 }
4924 } 4923 }
4925 4924
diff --git a/src/image.c b/src/image.c
index 00d1836116f..c085e6e63eb 100644
--- a/src/image.c
+++ b/src/image.c
@@ -316,7 +316,6 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file)
316 int xhot, yhot, result; 316 int xhot, yhot, result;
317 ptrdiff_t id; 317 ptrdiff_t id;
318 Lisp_Object found; 318 Lisp_Object found;
319 int fd;
320 char *filename; 319 char *filename;
321 320
322 /* Look for an existing bitmap with the same name. */ 321 /* Look for an existing bitmap with the same name. */
@@ -332,10 +331,8 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file)
332 } 331 }
333 332
334 /* Search bitmap-file-path for the file, if appropriate. */ 333 /* Search bitmap-file-path for the file, if appropriate. */
335 fd = openp (Vx_bitmap_file_path, file, Qnil, &found, Qnil); 334 if (openp (Vx_bitmap_file_path, file, Qnil, &found, make_number (R_OK)) < 0)
336 if (fd < 0)
337 return -1; 335 return -1;
338 emacs_close (fd);
339 336
340 filename = SSDATA (found); 337 filename = SSDATA (found);
341 338
diff --git a/src/lisp.h b/src/lisp.h
index 4af256f54b6..a54b2e07057 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3822,6 +3822,7 @@ extern Lisp_Object expand_and_dir_to_file (Lisp_Object, Lisp_Object);
3822EXFUN (Fread_file_name, 6); /* Not a normal DEFUN. */ 3822EXFUN (Fread_file_name, 6); /* Not a normal DEFUN. */
3823extern Lisp_Object close_file_unwind (Lisp_Object); 3823extern Lisp_Object close_file_unwind (Lisp_Object);
3824extern Lisp_Object restore_point_unwind (Lisp_Object); 3824extern Lisp_Object restore_point_unwind (Lisp_Object);
3825extern _Noreturn void report_file_errno (const char *, Lisp_Object, int);
3825extern _Noreturn void report_file_error (const char *, Lisp_Object); 3826extern _Noreturn void report_file_error (const char *, Lisp_Object);
3826extern bool internal_delete_file (Lisp_Object); 3827extern bool internal_delete_file (Lisp_Object);
3827extern Lisp_Object emacs_readlinkat (int, const char *); 3828extern Lisp_Object emacs_readlinkat (int, const char *);
diff --git a/src/lread.c b/src/lread.c
index 5729cca9560..f0423f166dd 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1412,7 +1412,7 @@ directories, make sure the PREDICATE function returns `dir-ok' for them. */)
1412{ 1412{
1413 Lisp_Object file; 1413 Lisp_Object file;
1414 int fd = openp (path, filename, suffixes, &file, predicate); 1414 int fd = openp (path, filename, suffixes, &file, predicate);
1415 if (NILP (predicate) && fd > 0) 1415 if (NILP (predicate) && fd >= 0)
1416 emacs_close (fd); 1416 emacs_close (fd);
1417 return file; 1417 return file;
1418} 1418}
diff --git a/src/process.c b/src/process.c
index 81be29082fc..4a38c47443a 100644
--- a/src/process.c
+++ b/src/process.c
@@ -1616,6 +1616,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1616{ 1616{
1617 int inchannel, outchannel; 1617 int inchannel, outchannel;
1618 pid_t pid; 1618 pid_t pid;
1619 int vfork_errno;
1619 int sv[2]; 1620 int sv[2];
1620#ifndef WINDOWSNT 1621#ifndef WINDOWSNT
1621 int wait_child_setup[2]; 1622 int wait_child_setup[2];
@@ -1656,9 +1657,10 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1656 forkout = sv[1]; 1657 forkout = sv[1];
1657 if (pipe2 (sv, O_CLOEXEC) != 0) 1658 if (pipe2 (sv, O_CLOEXEC) != 0)
1658 { 1659 {
1660 int pipe_errno = errno;
1659 emacs_close (inchannel); 1661 emacs_close (inchannel);
1660 emacs_close (forkout); 1662 emacs_close (forkout);
1661 report_file_error ("Creating pipe", Qnil); 1663 report_file_errno ("Creating pipe", Qnil, pipe_errno);
1662 } 1664 }
1663 outchannel = sv[1]; 1665 outchannel = sv[1];
1664 forkin = sv[0]; 1666 forkin = sv[0];
@@ -1837,6 +1839,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1837 1839
1838 /* Back in the parent process. */ 1840 /* Back in the parent process. */
1839 1841
1842 vfork_errno = errno;
1840 XPROCESS (process)->pid = pid; 1843 XPROCESS (process)->pid = pid;
1841 if (pid >= 0) 1844 if (pid >= 0)
1842 XPROCESS (process)->alive = 1; 1845 XPROCESS (process)->alive = 1;
@@ -1851,6 +1854,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1851 emacs_close (forkin); 1854 emacs_close (forkin);
1852 if (forkin != forkout && forkout >= 0) 1855 if (forkin != forkout && forkout >= 0)
1853 emacs_close (forkout); 1856 emacs_close (forkout);
1857 report_file_errno ("Doing vfork", Qnil, vfork_errno);
1854 } 1858 }
1855 else 1859 else
1856 { 1860 {
@@ -1896,10 +1900,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1896 } 1900 }
1897#endif 1901#endif
1898 } 1902 }
1899
1900 /* Now generate the error if vfork failed. */
1901 if (pid < 0)
1902 report_file_error ("Doing vfork", Qnil);
1903} 1903}
1904 1904
1905void 1905void
@@ -3265,12 +3265,11 @@ usage: (make-network-process &rest ARGS) */)
3265 3265
3266 len = sizeof xerrno; 3266 len = sizeof xerrno;
3267 eassert (FD_ISSET (s, &fdset)); 3267 eassert (FD_ISSET (s, &fdset));
3268 if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) == -1) 3268 if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) < 0)
3269 report_file_error ("getsockopt failed", Qnil); 3269 report_file_error ("getsockopt failed", Qnil);
3270 if (xerrno) 3270 if (xerrno)
3271 errno = xerrno, report_file_error ("error during connect", Qnil); 3271 report_file_errno ("error during connect", Qnil, xerrno);
3272 else 3272 break;
3273 break;
3274 } 3273 }
3275#endif /* !WINDOWSNT */ 3274#endif /* !WINDOWSNT */
3276 3275
@@ -3354,11 +3353,10 @@ usage: (make-network-process &rest ARGS) */)
3354 if (is_non_blocking_client) 3353 if (is_non_blocking_client)
3355 return Qnil; 3354 return Qnil;
3356 3355
3357 errno = xerrno; 3356 report_file_errno ((is_server
3358 if (is_server) 3357 ? "make server process failed"
3359 report_file_error ("make server process failed", contact); 3358 : "make client process failed"),
3360 else 3359 contact, xerrno);
3361 report_file_error ("make client process failed", contact);
3362 } 3360 }
3363 3361
3364 inch = s; 3362 inch = s;
diff --git a/src/unexaix.c b/src/unexaix.c
index 45b3ca667b0..757ba6f51b3 100644
--- a/src/unexaix.c
+++ b/src/unexaix.c
@@ -94,13 +94,10 @@ static int pagemask;
94static _Noreturn void 94static _Noreturn void
95report_error (const char *file, int fd) 95report_error (const char *file, int fd)
96{ 96{
97 int err = errno;
97 if (fd) 98 if (fd)
98 { 99 emacs_close (fd);
99 int failed_errno = errno; 100 report_file_errno ("Cannot unexec", Fcons (build_string (file), Qnil), err);
100 emacs_close (fd);
101 errno = failed_errno;
102 }
103 report_file_error ("Cannot unexec", Fcons (build_string (file), Qnil));
104} 101}
105 102
106#define ERROR0(msg) report_error_1 (new, msg) 103#define ERROR0(msg) report_error_1 (new, msg)
diff --git a/src/unexcoff.c b/src/unexcoff.c
index 6b2a3336c8a..c467e59a665 100644
--- a/src/unexcoff.c
+++ b/src/unexcoff.c
@@ -127,9 +127,10 @@ static int pagemask;
127static void 127static void
128report_error (const char *file, int fd) 128report_error (const char *file, int fd)
129{ 129{
130 int err = errno;
130 if (fd) 131 if (fd)
131 emacs_close (fd); 132 emacs_close (fd);
132 report_file_error ("Cannot unexec", Fcons (build_string (file), Qnil)); 133 report_file_errno ("Cannot unexec", Fcons (build_string (file), Qnil), err);
133} 134}
134 135
135#define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1 136#define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1