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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.