diff options
| author | Paul Eggert | 2013-07-12 10:30:48 -0700 |
|---|---|---|
| committer | Paul Eggert | 2013-07-12 10:30:48 -0700 |
| commit | a773ed9ac83b950cb2a934e9d54e1880f44bd350 (patch) | |
| tree | aa859e605867e85ae4fdee5401deddb18e0a630a /src | |
| parent | 7e649856bce883738622cc3533ad808c6ea1a73f (diff) | |
| download | emacs-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/ChangeLog | 23 | ||||
| -rw-r--r-- | src/callproc.c | 74 | ||||
| -rw-r--r-- | src/fileio.c | 81 | ||||
| -rw-r--r-- | src/image.c | 5 | ||||
| -rw-r--r-- | src/lisp.h | 1 | ||||
| -rw-r--r-- | src/lread.c | 2 | ||||
| -rw-r--r-- | src/process.c | 26 | ||||
| -rw-r--r-- | src/unexaix.c | 9 | ||||
| -rw-r--r-- | src/unexcoff.c | 3 |
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 @@ | |||
| 1 | 2013-07-12 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2013-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 | |||
| 162 | void | 165 | void |
| 163 | report_file_error (const char *string, Lisp_Object data) | 166 | report_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 | ||
| 201 | void | ||
| 202 | report_file_error (char const *string, Lisp_Object data) | ||
| 203 | { | ||
| 204 | report_file_errno (string, data, errno); | ||
| 205 | } | ||
| 206 | |||
| 199 | Lisp_Object | 207 | Lisp_Object |
| 200 | close_file_unwind (Lisp_Object fd) | 208 | close_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); | |||
| 3822 | EXFUN (Fread_file_name, 6); /* Not a normal DEFUN. */ | 3822 | EXFUN (Fread_file_name, 6); /* Not a normal DEFUN. */ |
| 3823 | extern Lisp_Object close_file_unwind (Lisp_Object); | 3823 | extern Lisp_Object close_file_unwind (Lisp_Object); |
| 3824 | extern Lisp_Object restore_point_unwind (Lisp_Object); | 3824 | extern Lisp_Object restore_point_unwind (Lisp_Object); |
| 3825 | extern _Noreturn void report_file_errno (const char *, Lisp_Object, int); | ||
| 3825 | extern _Noreturn void report_file_error (const char *, Lisp_Object); | 3826 | extern _Noreturn void report_file_error (const char *, Lisp_Object); |
| 3826 | extern bool internal_delete_file (Lisp_Object); | 3827 | extern bool internal_delete_file (Lisp_Object); |
| 3827 | extern Lisp_Object emacs_readlinkat (int, const char *); | 3828 | extern 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 | ||
| 1905 | void | 1905 | void |
| @@ -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; | |||
| 94 | static _Noreturn void | 94 | static _Noreturn void |
| 95 | report_error (const char *file, int fd) | 95 | report_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; | |||
| 127 | static void | 127 | static void |
| 128 | report_error (const char *file, int fd) | 128 | report_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 |