This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


On 2018-06-28 10:28, Craig Howland wrote:
> On 06/27/2018 08:55 AM, Corinna Vinschen wrote:
>> On Jun 27 20:01, Takashi Yano wrote:
>>> POSIX states:
>>> The perror() function shall not change the orientation of the standard
>>> error stream.
>>> However, cygwin perror() function changes the orientation of stderr to
>>> byte-oriented mode if stderr is not oriented yet.
> I suggest that POSIX is in error.  The POSIX statement about not changing the
> orientation is an extension to the C standard (CX, to be precise).  POSIX is
> always careful to defer to the C standard, which I think does indirectly specify
> that perror() is byte-oriented.  The C standard actually does not directly talk
> about the orientation of perror().  However, it directly defines (quoting from
> the N1570 C11 draft):
> 
> "The input/output functions are given the following collective terms:
> — The wide character input functions — those functions described in 7.29 that
> perform input into wide characters and wide strings: fgetwc, fgetws, getwc,
> getwchar, fwscanf, wscanf, vfwscanf, and vwscanf.
> — The wide character output functions — those functions described in 7.29 that
> perform output from wide characters and wide strings: fputwc, fputws, putwc,
> putwchar, fwprintf, wprintf, vfwprintf, and vwprintf.
> — The wide character input/output functions — the union of the ungetwc function,
> the wide character input functions, and the wide character output functions.
> — The byte input/output functions — those functions described in this subclause
> that perform input/output: fgetc, fgets, fprintf, fputc, fputs, fread, fscanf,
> fwrite, getc, getchar, printf, putc, putchar, puts, scanf, ungetc, vfprintf,
> vfscanf, vprintf, and vscanf."

INCITS/ISO/IEC 9899-2011[2012] 7.21 Input/output <stdio.h> 7.21.1 Introduction
#5 is exactly the same.

However 7.21.3 Files #13 states:
"In some cases, some of the byte input/output functions also perform conversions
between multibyte characters and wide characters. These conversions also occur
as if by calls to the mbrtowc and wcrtomb functions."

This seems to allow for input/output functions not listed in 7.21.1#5 to adapt
to the stream orientation by using the stream's character input/output
conversion functions, which could be as above, or a nop.

> Please note that perror() is not listed.  While this could be interpreted to
> mean it can be both, the proper way for that have to been done would be for it
> to appear in both lists--which it does not.  However, perror() is defined in the
> same stdio.h subclause (i.e. 7.21) as all of the byte functions, against the
> wide-character functions in wchar.h (7.29).  So even though the C standard is
> sloppy and does not directly have perror() in the enumerated list, it is
> included by the general statement about the subclause. However, you could argue
> that it was purposely left out, which is why they bothered to list the others. 
> Against this are the definition or perror(), itself, and that they really should
> have listed perror() as an exception if it was so intended, and (as
> already-mentioned) perror() should be in both lists if it is to be dual-oriented.
> 
> Here is the argument based on the perror() definition:
> 
> "void perror(const char *s);
> ...
> It writes a sequence of characters to the standard error stream thus: first (if s
> is not a null pointer and the character pointed to by s is not the null
> character), the string pointed to by s followed by a colon (:) and a space; then
> an appropriate error message string followed by a new-line character."
> 
> Things to note:
> 1)  It is a regular character pointer, not a wide character pointer.  Those
> characters, if supplied, are written.  (It says nothing about converting them to
> wide if need be, it says "the string pointed to by s".)
> 2)  "error message string".  It does not say 'or wide-character error message
> string if needed'.
> 3)  Followed by a "new-line character".  It does not say "new-line wide
> character", which is used throughout the wchar.h section (7.29).
> 
> So there is definitely a weakness in the C standard, but I think it is clear
> that perror() is a byte output function.  If the user wants to print to a
> wide-character stream, the only pure way to do it would be to turn strerror()
> (used by perror()) output into a wide-character string.  POSIX noted this
> weakness, but fixed it with a bad extension, rather than classifying perror() as
> byte--which is clearly is.
> 
> Therefore, the newlib perror() behavior is correct and should not be changed. 
> It definitely is a mess and there really ought to be a perrorw() function.
> 
> (Granted, I should probably submit these arguments to POSIX for evaluation, but
> I don't know how.  Perhaps Eric Blake might be able to help with this,
> potentially with an off-list discussion.)

Joseph Myers has some experience submitting C DRs to JTC1/SC22/WG14, who should
be responsible for any clarification required. Discussions are better on-list.

-- 
Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]