Re: perror() changes the orientation of stderr to byte-oriented mode if stderr is not oriented yet.
Takashi Yano <[email protected]>
| Newsgroups | gmane.comp.lib.newlib |
|---|---|
| Message-ID | <[email protected]> |
Hi Corinna, On Mon, 2 Jul 2018 12:28:38 +0200 Corinna Vinschen wrote: > Not sure if I'm missing something, but doesn't that mean the perror > output won't use text mode even if it's requested? It seems that the text mode only affects to outputting '\n'. So, this is maintained in the patch. However, this is not so smart. > I guess the simplest solution is to use the FreeBSD/OpenBSD method > all the time. How about the patch attached? -- Takashi Yano <[email protected]>
0001-Fix-a-bug-of-perror-psignal-that-changes-the-orienta.patch
(application/octet-stream, 2.8 KB)
From 80be9c95f8e48a516705b61077f8dd84e2e26878 Mon Sep 17 00:00:00 2001 From: Takashi Yano <[email protected]> Date: Tue, 3 Jul 2018 18:04:31 +0900 Subject: [PATCH] Fix a bug of perror()/psignal() that changes the orientation of stderr. * perror.c: Fix the problem that perror() changes the orientation of stderr ty byte-oriented mode if stderr is not oriented yet. * psignal.c: Ditto. --- newlib/libc/signal/psignal.c | 30 +++++++++++++++++++++++++++--- newlib/libc/stdio/perror.c | 32 +++++++++++++++++++++++++++----- 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/newlib/libc/signal/psignal.c b/newlib/libc/signal/psignal.c index 602714f49..9a584869d 100644 --- a/newlib/libc/signal/psignal.c +++ b/newlib/libc/signal/psignal.c @@ -32,13 +32,37 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, #include <_ansi.h> #include <stdio.h> #include <string.h> +#include <sys/uio.h> + +#define ADD(str) \ +{ \ + v->iov_base = (void *)(str); \ + v->iov_len = strlen (v->iov_base); \ + v ++; \ + iov_cnt ++; \ +} void psignal (int sig, const char *s) { + struct iovec iov[4]; + struct iovec *v = iov; + int iov_cnt = 0; + if (s != NULL && *s != '\0') - fprintf (stderr, "%s: %s\n", s, strsignal (sig)); - else - fprintf (stderr, "%s\n", strsignal (sig)); + { + ADD (s); + ADD (": "); + } + ADD (strsignal (sig)); + +#ifdef __SCLE + ADD ((stderr->_flags & __SCLE) ? "\r\n" : "\n"); +#else + ADD ("\n"); +#endif + + fflush (stderr); + writev (fileno (stderr), iov, iov_cnt); } diff --git a/newlib/libc/stdio/perror.c b/newlib/libc/stdio/perror.c index d98e17e19..831c67eef 100644 --- a/newlib/libc/stdio/perror.c +++ b/newlib/libc/stdio/perror.c @@ -56,26 +56,48 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, #include <reent.h> #include <stdio.h> #include <string.h> +#include <sys/uio.h> #include "local.h" +#define ADD(str) \ +{ \ + v->iov_base = (void *)(str); \ + v->iov_len = strlen (v->iov_base); \ + v ++; \ + iov_cnt ++; \ +} + void _perror_r (struct _reent *ptr, const char *s) { char *error; int dummy; + struct iovec iov[4]; + struct iovec *v = iov; + int iov_cnt = 0; + FILE *fp = _stderr_r (ptr); - _REENT_SMALL_CHECK_INIT (ptr); + CHECK_INIT (ptr, fp); if (s != NULL && *s != '\0') { - fputs (s, _stderr_r (ptr)); - fputs (": ", _stderr_r (ptr)); + ADD (s); + ADD (": "); } if ((error = _strerror_r (ptr, ptr->_errno, 1, &dummy)) != NULL) - fputs (error, _stderr_r (ptr)); + ADD (error); + +#ifdef __SCLE + ADD ((fp->_flags & __SCLE) ? "\r\n" : "\n"); +#else + ADD ("\n"); +#endif - fputc ('\n', _stderr_r (ptr)); + _newlib_flockfile_start (fp); + fflush (fp); + writev (fileno (fp), iov, iov_cnt); + _newlib_flockfile_end (fp); } #ifndef _REENT_ONLY -- 2.17.0