[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Nmh-workers] Proposed solution to Debian Bug#143485
From: |
Harald Geyer |
Subject: |
Re: [Nmh-workers] Proposed solution to Debian Bug#143485 |
Date: |
Sat, 27 Aug 2005 12:18:40 +0200 |
Hi Ralph,
> > Hm, I think if write(2, ...) fails, then we are out of luck anyway. We
> > can't give an error message about being unable to give an error
> > message. I thought that a successful call of write won't manipulate
> > errno, but after rereading the documentation of errno it seems that
> > one can't rely on this.
>
> That's correct.
>
> > On the other hand it says, that one can detect an error by explictely
> > setting errno=0 before the call and testing errno afterwards.
>
> That's not true. What wording does your man page have exactly? It's
> only meaningful to read errno when some other error indication has
> occurred, e.g. write(2) returning -1.
It says: "Sometimes, when -1 is also a valid successful return value
one has to zero errno before the call in order to detect possible errors."
> > It also says that errno is never set to zero by the library.
>
> That's true.
>
> http://www.dinkumware.com/manuals/reader.aspx?b=c/&h=errno.html
> "Library functions store only values greater than zero."
>
> > So I'm now a bit confused about how write is allowed to change errno
> > on success...
>
> A library call may do several things internally and one of them may
> error but the overall call doesn't fail, e.g. printf() checking if
> stdout is a tty can set errno to ENOTTY but the printf() succeeds.
>
> http://www.eskimo.com/~scs/C-faq/q12.24.html
> Why does errno contain ENOTTY after a call to printf?
>
> write(2) may not do this, but the general convention holds.
>
> Take strtod(3), it returns a double.
>
> "If the correct value would cause underflow, zero is returned and
> ERANGE is stored in errno."
>
> If strtod() returns 0 we don't know if the string passed was "0" or
> whether underflow has occurred; we need to inspect errno. But
>
> if (strtod(s) == 0 && errno == ERANGE) {
>
> is incorrect since errno may be there from an earlier strtod(), or
> something else.
>
> errno = 0;
> if (strtod(s) == 0 && errno == ERANGE) {
>
> is the correct way.
Thanks, for the lessons in C und Unix to you and Robert.
Harald