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]>
On Thu, 5 Jul 2018 14:49:00 +0200
Corinna Vinschen wrote:
> ...I noticed that FreeBSD handles psignal differently.  It writes the
> output immediately to STDERR_FILENO, rather than to stderr or
> fileno(stderr).  It does also not call fflush or reset the _SOFF flag.
...
> Thoughts?

Since _newlib_flockfile_start()/end() are defined in stdio/local.h, using
_newlib_flockfile_start()/end() from psignal.c is a bit painful. Moreover
there are several reports that they can not build newlib on bare metal.
Therefore, I imitated FreeBSD in a hurry just because it seems the easiest
way.

-- 
Takashi Yano <[email protected]>
0001-Fix-newlib-functions-perror-psignal-not-to-use-write.patch (application/octet-stream, 3.5 KB)
From 598ebd7885da2bf1bb3dfc7fc60977d74b47caed Mon Sep 17 00:00:00 2001
From: Takashi Yano <[email protected]>
Date: Thu, 5 Jul 2018 23:01:26 +0900
Subject: [PATCH] Fix newlib functions perror()/psignal() not to use writev().

This fix is for some platforms which do not have writev().
*perror.c: Use _write_r() instead of writev().
*psignal.c: Use write() insetad of writev().

Revise commit: d4f4e7ae1be1bcf8c021f2b0865aafc16b338aa3
---
 newlib/libc/signal/psignal.c | 36 ++++++++++++++++----------------
 newlib/libc/stdio/perror.c   | 40 +++++++++++++++++++-----------------
 2 files changed, 39 insertions(+), 37 deletions(-)

diff --git a/newlib/libc/signal/psignal.c b/newlib/libc/signal/psignal.c
index 9a584869d..f847ab2c8 100644
--- a/newlib/libc/signal/psignal.c
+++ b/newlib/libc/signal/psignal.c
@@ -32,37 +32,37 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
 #include <_ansi.h>
 #include <stdio.h>
 #include <string.h>
-#include <sys/uio.h>
+#include <unistd.h>
 
-#define ADD(str) \
+#define WRITE_STR(str) \
 { \
-  v->iov_base = (void *)(str); \
-  v->iov_len = strlen (v->iov_base); \
-  v ++; \
-  iov_cnt ++; \
+  const char *p = (str); \
+  size_t len = strlen (p); \
+  while (len) \
+    { \
+      ssize_t len1 = write (fileno (stderr), p, len); \
+      if (len1 < 0) \
+	break; \
+      len -= len1; \
+      p += len1; \
+    } \
 }
 
 void
 psignal (int sig,
        const char *s)
 {
-  struct iovec iov[4];
-  struct iovec *v = iov;
-  int iov_cnt = 0;
-
+  fflush (stderr);
   if (s != NULL && *s != '\0')
     {
-      ADD (s);
-      ADD (": ");
+      WRITE_STR (s);
+      WRITE_STR (": ");
     }
-  ADD (strsignal (sig));
+  WRITE_STR (strsignal (sig));
 
 #ifdef __SCLE
-  ADD ((stderr->_flags & __SCLE) ? "\r\n" : "\n");
+  WRITE_STR ((stderr->_flags & __SCLE) ? "\r\n" : "\n");
 #else
-  ADD ("\n");
+  WRITE_STR ("\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 831c67eef..68d78c227 100644
--- a/newlib/libc/stdio/perror.c
+++ b/newlib/libc/stdio/perror.c
@@ -56,15 +56,20 @@ 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) \
+#define WRITE_STR(str) \
 { \
-  v->iov_base = (void *)(str); \
-  v->iov_len = strlen (v->iov_base); \
-  v ++; \
-  iov_cnt ++; \
+  const char *p = (str); \
+  size_t len = strlen (p); \
+  while (len) \
+    { \
+      ssize_t len1 = _write_r (ptr, fileno (fp), p, len); \
+      if (len1 < 0) \
+	break; \
+      len -= len1; \
+      p += len1; \
+    } \
 }
 
 void
@@ -73,31 +78,28 @@ _perror_r (struct _reent *ptr,
 {
   char *error;
   int dummy;
-  struct iovec iov[4];
-  struct iovec *v = iov;
-  int iov_cnt = 0;
   FILE *fp = _stderr_r (ptr);
 
   CHECK_INIT (ptr, fp);
+
+  _newlib_flockfile_start(fp);
+  _fflush_r (ptr, fp);
   if (s != NULL && *s != '\0')
     {
-      ADD (s);
-      ADD (": ");
+      WRITE_STR (s);
+      WRITE_STR (": ");
     }
 
   if ((error = _strerror_r (ptr, ptr->_errno, 1, &dummy)) != NULL)
-    ADD (error);
+    WRITE_STR (error);
 
 #ifdef __SCLE
-  ADD ((fp->_flags & __SCLE) ? "\r\n" : "\n");
+  WRITE_STR ((fp->_flags & __SCLE) ? "\r\n" : "\n");
 #else
-  ADD ("\n");
+  WRITE_STR ("\n");
 #endif
-
-  _newlib_flockfile_start (fp);
-  fflush (fp);
-  writev (fileno (fp), iov, iov_cnt);
-  _newlib_flockfile_end (fp);
+  fp->_flags &= ~__SOFF;
+  _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.