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]> |
I am not in a position to comment whether POSIX is wrong or not, so nothing about that. On Thu, 28 Jun 2018 20:31:57 +0200 Corinna Vinschen wrote: > > I tried this but it failed because __sputc_r() called from _fputs_r also > > sets orientation. So I have borrowed the codes from __swbuf_r() in wbuf.c > > so that the strings are pushed directly into the buffer. > > I did. Thanks for implementing this, but... uhm... I'm not really > thrilled. So much extra code for such a simple thing as perror...? > > On second thought I wonder if we shouldn't just go the FreeBSD route. Maybe. But I have another possibility. What about this one? By the way, I have noticed that psignal() and psiginfo() also have the same problem. psignal() belongs to newlib, so the same strategy can be applied. However, what can we do for psiginfo()? Only the FreeBSD route may be the answer... -- Takashi Yano <[email protected]>
0001-Fix-a-bug-of-perror-which-changes-the-orientation-of.patch
(application/octet-stream, 2.1 KB)
From 05c640812531f758d42502f4c144ee09f82406ee Mon Sep 17 00:00:00 2001 From: Takashi Yano <[email protected]> Date: Fri, 29 Jun 2018 21:19:50 +0900 Subject: [PATCH] Fix a bug of perror() which changes the orientation of stderr. * perror.c: Fix the problem that perror() changes the orientation of stderr to byte-oriented mode if stderr is not oriented yet. --- newlib/libc/stdio/perror.c | 44 ++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/newlib/libc/stdio/perror.c b/newlib/libc/stdio/perror.c index d98e17e19..dd277370a 100644 --- a/newlib/libc/stdio/perror.c +++ b/newlib/libc/stdio/perror.c @@ -56,26 +56,58 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, #include <reent.h> #include <stdio.h> #include <string.h> +#include "fvwrite.h" #include "local.h" +#define ADD(str) \ +{ \ + v->iov_base = (str); \ + v->iov_len = strlen (v->iov_base); \ + uio.uio_iovcnt++; \ + uio.uio_resid += v->iov_len; \ + v++; \ +} + void _perror_r (struct _reent *ptr, const char *s) { char *error; int dummy; + struct __suio uio; + struct __siov iov[4]; + struct __siov *v; + short flag_scle = 0; + FILE *fp; + + fp = _stderr_r (ptr); - _REENT_SMALL_CHECK_INIT (ptr); + CHECK_INIT (ptr, fp); + + uio.uio_iov = v = iov; + uio.uio_iovcnt = 0; + uio.uio_resid = 0; 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)); - - fputc ('\n', _stderr_r (ptr)); + ADD (error); +#ifdef __SCLE + flag_scle = fp->_flags & __SCLE; +#endif + ADD (flag_scle ? "\r\n" : "\n"); + + _newlib_flockfile_start (fp); + /* The orientation is set in __sfvwrite_r() if __SCLE is set. + Therefore unset __SCLE temporarily, and restore it after + calling __sfvwrite_r(). */ + fp->_flags &= ~flag_scle; + __sfvwrite_r (ptr, fp, &uio); + fp->_flags |= flag_scle; + _newlib_flockfile_end (fp); } #ifndef _REENT_ONLY -- 2.17.0