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 Thu, 5 Jul 2018 11:08:51 +0200
Corinna Vinschen wrote:
> Ouch!  I didn't realize that writev is not a required function on
> bare metal, sorry.
> 
> Takashi, we need a patch to implement perror/psignal without writev, for
> instance by calling write twice.  Care to send a followup patch?

Patch attached.

I am not sure whether _newlib_flockfile_start()/end() is necessary or not.
Could you please check?

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

This fix is for some platforms which does 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 | 35 +++++++++++++++++------------------
 newlib/libc/stdio/perror.c   | 36 +++++++++++++++++-------------------
 2 files changed, 34 insertions(+), 37 deletions(-)

diff --git a/newlib/libc/signal/psignal.c b/newlib/libc/signal/psignal.c
index 9a584869d..522fc79f2 100644
--- a/newlib/libc/signal/psignal.c
+++ b/newlib/libc/signal/psignal.c
@@ -32,37 +32,36 @@ 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..9527939ee 100644
--- a/newlib/libc/stdio/perror.c
+++ b/newlib/libc/stdio/perror.c
@@ -56,15 +56,19 @@ 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 +77,25 @@ _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);
+
+  fflush (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);
 }
 
 #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.