perror() changes the orientation of stderr to byte-oriented mode if stderr is not oriented yet.

Corinna Vinschen vinschen@redhat.com
Thu Jul 5 11:21:00 GMT 2018


On Jul  5 19:41, Takashi Yano wrote:
> 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?

Yes, we need it, the entire operation, flushing and writing, must be
cancel-safe and synchronized with other access to the stderr FILE.

Comparing with FreeBSD, there's also something missing.  After the
write operation, the offset in the FILE structure is incorrect.
Consequentially the __SOFF flag is reset to 0 last thing before
unlocking the file:

  stderr->_flags &= ~__SOFF;

Also:

> +#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; \

Please put the break on a line of its own:

   if (len1 < 0) \
     break; \

> [...]
> +#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; \

Ditto.

> +      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);

I only just noticed, sorry.  Please call

     _fflush_r (ptr, fp);


Thanks,
Corinna

-- 
Corinna Vinschen
Cygwin Maintainer
Red Hat
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/newlib/attachments/20180705/c7237502/attachment.sig>


More information about the Newlib mailing list