diff options
| author | Paul Eggert | 2016-04-04 09:36:30 -0700 |
|---|---|---|
| committer | Paul Eggert | 2016-04-04 09:44:19 -0700 |
| commit | 6bccb19c9bef1189c8e853ff7cc16b889a3a57e3 (patch) | |
| tree | 9555d6605362ec0c452b343d549d2af3c983415d /src/print.c | |
| parent | a11756ad0e2ee719266c0081150c20996cce8e0d (diff) | |
| download | emacs-6bccb19c9bef1189c8e853ff7cc16b889a3a57e3.tar.gz emacs-6bccb19c9bef1189c8e853ff7cc16b889a3a57e3.zip | |
Port redirect-debugging-output to non-GNU/Linux
Problem reported by Kylie McClain for musl in:
http://lists.gnu.org/archive/html/emacs-devel/2016-03/msg01592.html
* etc/DEBUG, etc/NEWS: Mention this.
* src/callproc.c (child_setup) [!MSDOS]:
* src/dispnew.c (init_display):
* src/emacs.c (main, Fdaemon_initialized):
* src/minibuf.c (read_minibuf_noninteractive):
* src/regex.c (xmalloc, xrealloc):
Prefer symbolic names like STDERR_FILENO to magic numbers like 2,
to make file-descriptor manipulation easier to follow.
* src/emacs.c (relocate_fd) [!WINDOWSNT]: Remove; no longer needed
now that we make sure stdin, stdout and stderr are open. All uses
removed.
(main): Make sure standard FDs are OK. Prefer symbolic names like
EXIT_FAILURE to magic numbers like 1. Use bool for boolean.
* src/lisp.h (init_standard_fds): New decl.
* src/print.c (WITH_REDIRECT_DEBUGGING_OUTPUT) [GNU_LINUX]:
Remove; no longer needed.
(Fredirect_debugging_output): Define on all platforms, not just
GNU/Linux. Redirect file descriptor, not stream, so that the code
works even if stderr is not an lvalue. Report an error if the
file arg is neither a string nor nil.
(syms_of_print): Always define redirect-debugging-output.
* src/sysdep.c (force_open, init_standard_fds): New functions.
Diffstat (limited to 'src/print.c')
| -rw-r--r-- | src/print.c | 51 |
1 files changed, 24 insertions, 27 deletions
diff --git a/src/print.c b/src/print.c index 2b53d7580b1..db2918ff478 100644 --- a/src/print.c +++ b/src/print.c | |||
| @@ -775,15 +775,6 @@ debug_output_compilation_hack (bool x) | |||
| 775 | print_output_debug_flag = x; | 775 | print_output_debug_flag = x; |
| 776 | } | 776 | } |
| 777 | 777 | ||
| 778 | #if defined (GNU_LINUX) | ||
| 779 | |||
| 780 | /* This functionality is not vitally important in general, so we rely on | ||
| 781 | non-portable ability to use stderr as lvalue. */ | ||
| 782 | |||
| 783 | #define WITH_REDIRECT_DEBUGGING_OUTPUT 1 | ||
| 784 | |||
| 785 | static FILE *initial_stderr_stream = NULL; | ||
| 786 | |||
| 787 | DEFUN ("redirect-debugging-output", Fredirect_debugging_output, Sredirect_debugging_output, | 778 | DEFUN ("redirect-debugging-output", Fredirect_debugging_output, Sredirect_debugging_output, |
| 788 | 1, 2, | 779 | 1, 2, |
| 789 | "FDebug output file: \nP", | 780 | "FDebug output file: \nP", |
| @@ -793,30 +784,38 @@ Optional arg APPEND non-nil (interactively, with prefix arg) means | |||
| 793 | append to existing target file. */) | 784 | append to existing target file. */) |
| 794 | (Lisp_Object file, Lisp_Object append) | 785 | (Lisp_Object file, Lisp_Object append) |
| 795 | { | 786 | { |
| 796 | if (initial_stderr_stream != NULL) | 787 | /* If equal to STDERR_FILENO, stderr has not been duplicated and is OK as-is. |
| 797 | { | 788 | Otherwise, this is a close-on-exec duplicate of the original stderr. */ |
| 798 | block_input (); | 789 | static int stderr_dup = STDERR_FILENO; |
| 799 | fclose (stderr); | 790 | int fd = stderr_dup; |
| 800 | unblock_input (); | ||
| 801 | } | ||
| 802 | stderr = initial_stderr_stream; | ||
| 803 | initial_stderr_stream = NULL; | ||
| 804 | 791 | ||
| 805 | if (STRINGP (file)) | 792 | if (! NILP (file)) |
| 806 | { | 793 | { |
| 807 | file = Fexpand_file_name (file, Qnil); | 794 | file = Fexpand_file_name (file, Qnil); |
| 808 | initial_stderr_stream = stderr; | 795 | |
| 809 | stderr = emacs_fopen (SSDATA (file), NILP (append) ? "w" : "a"); | 796 | if (stderr_dup == STDERR_FILENO) |
| 810 | if (stderr == NULL) | ||
| 811 | { | 797 | { |
| 812 | stderr = initial_stderr_stream; | 798 | int n = fcntl (STDERR_FILENO, F_DUPFD_CLOEXEC, STDERR_FILENO + 1); |
| 813 | initial_stderr_stream = NULL; | 799 | if (n < 0) |
| 814 | report_file_error ("Cannot open debugging output stream", file); | 800 | report_file_error ("dup", file); |
| 801 | stderr_dup = n; | ||
| 815 | } | 802 | } |
| 803 | |||
| 804 | fd = emacs_open (SSDATA (ENCODE_FILE (file)), | ||
| 805 | (O_WRONLY | O_CREAT | ||
| 806 | | (! NILP (append) ? O_APPEND : O_TRUNC)), | ||
| 807 | 0666); | ||
| 808 | if (fd < 0) | ||
| 809 | report_file_error ("Cannot open debugging output stream", file); | ||
| 816 | } | 810 | } |
| 811 | |||
| 812 | fflush (stderr); | ||
| 813 | if (dup2 (fd, STDERR_FILENO) < 0) | ||
| 814 | report_file_error ("dup2", file); | ||
| 815 | if (fd != stderr_dup) | ||
| 816 | emacs_close (fd); | ||
| 817 | return Qnil; | 817 | return Qnil; |
| 818 | } | 818 | } |
| 819 | #endif /* GNU_LINUX */ | ||
| 820 | 819 | ||
| 821 | 820 | ||
| 822 | /* This is the interface for debugging printing. */ | 821 | /* This is the interface for debugging printing. */ |
| @@ -2305,9 +2304,7 @@ priorities. */); | |||
| 2305 | defsubr (&Sprint); | 2304 | defsubr (&Sprint); |
| 2306 | defsubr (&Sterpri); | 2305 | defsubr (&Sterpri); |
| 2307 | defsubr (&Swrite_char); | 2306 | defsubr (&Swrite_char); |
| 2308 | #ifdef WITH_REDIRECT_DEBUGGING_OUTPUT | ||
| 2309 | defsubr (&Sredirect_debugging_output); | 2307 | defsubr (&Sredirect_debugging_output); |
| 2310 | #endif | ||
| 2311 | 2308 | ||
| 2312 | DEFSYM (Qprint_escape_newlines, "print-escape-newlines"); | 2309 | DEFSYM (Qprint_escape_newlines, "print-escape-newlines"); |
| 2313 | DEFSYM (Qprint_escape_multibyte, "print-escape-multibyte"); | 2310 | DEFSYM (Qprint_escape_multibyte, "print-escape-multibyte"); |