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] | |
On 07/05/2018 08:49 AM, Corinna Vinschen wrote:
On Jul 5 20:35, Takashi Yano wrote:Hi Corinna, Thank you for checking. On Thu, 5 Jul 2018 13:19:21 +0200 Corinna Vinschen wrote: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;Do you mean these are necessary for both perror.c and psignal.c? How about psiginfo() case?Well, as long as we use the method at hand, I think it's the right thing to do. However... ...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. OpenBSD uses this method for perror as well, no syncing with stderr, no cancel-safety. GLibc duplicates the file descriptor in perror, but writes immediately to STDERR_FILENO in psiginfo, or uses an internal variation of fprintf in psignal (thus potentially changing the orientation). Ok, I'm a bit more puzzled than before. What all this is missing is *consistency*. I really wonder how standards-compliant this is. For all three functions POSIX says something like "... shall print a message out on stderr ...". stderr is the stream and it's underlying descriptor, not necessarily STDERR_FILENO. If immediate writing to STDERR_FILENO is ok, we should simply call write(STDERR_FILENO) and be done with it. Just like BSDs and Linux, we don't even have to loop until all bytes have been written, none of the above does. Thoughts? Corinna
POSIX defines all 3 functions with the same basic requirements, so it certainly does seem like whatever we do ought to be done in the same way for all 3. (I suppose you could make an argument that perror() is C while the other 2 are not, allowing a possible difference there. But that doesn't seem like a good idea.) I think that we're kind of stuck needing the fflush(). While I'd rather just skip it, not calling it can provide end behavior that is clearly different than perror()/etc. writing to the stream, itself, instead of calling write(2) (even if only when it is not unbuffered). That is, with a line or fully-buffered stream, anything in the stream buffer already at the time perror() is called should appear before the perror() output. If we don't flush, the in-buffer data appear after. The fflush() is what ends up making it look like we wrote to the stream using the more usual mechanism instead of write directly. That is, I think that with the fflush(), the end result should be the same as if we really were writing through the stream mechanism. (Although there's a complication related to timing, which is why I'm saying "end result" instead of "identical results." See below.) This means we would be statically standard compliant, even if the underlying mechanism is doing an end run around the usual internal stream write mechanisms.
To put this into a different form: lock stream stderr; fflush(stderr); write(fileno(stderr), string); unlock stream stderr; should produce the same end effect asfputs(stderr, string); /* (effectively what perror() is required to end up doing) */
in terms of the sequence of bytes which end up in the file.The former can produce a clear timing difference, however, although only if the stream is fully buffered: the fputs() output might not appear until something else is written (depending upon where the buffer fill happens to be), while the former case forces string out right away. This seems impossible to fix without returning to the full streams mechanism, but then we're back to the complex 'don't change the orientation' problem we're trying to avoid. It seems a small enough problem to accept, especially given the mess you're describing for the other libraries. Along the same lines, since they are supposed to write to the stream, strictly fileno(stderr) should be used, since it is possible for STDERR_FILENO (a fixed constant) to be inaccurate. This point really is independent of the fflush() question. (At least something seems easy to answer.)
Craig
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |