[newlib-cygwin] Fix a bug of perror()/psignal() that changes the orientation of stderr.

Corinna Vinschen corinna@sourceware.org
Wed Jul 4 12:19:00 GMT 2018


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=d4f4e7ae1be1bcf8c021f2b0865aafc16b338aa3

commit d4f4e7ae1be1bcf8c021f2b0865aafc16b338aa3
Author: Takashi Yano <takashi.yano@nifty.ne.jp>
Date:   Tue Jul 3 18:04:31 2018 +0900

    Fix a bug of perror()/psignal() that 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.
    * psignal.c: Ditto.

Diff:
---
 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 602714f..9a58486 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 d98e17e..831c67e 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



More information about the Newlib-cvs mailing list