errno questions (leading to a slightly OT follow-up question)

U

Urs Beeli

I have a question regarding errno. If I understand it correctly,
including <errno.h> allows me to check "errno" for error values
that some standard library functions may set.

This brings up some questions:

- As I understand it, most functions only set errno in an error
case. I take this to mean, that on success, errno is not
necessarily set to EOK and I would either need to set errno
to EOK before calling the function in question to determine
its outcome or I would need to check the return value first,
and then in an error case inspect errno to get more details.
Is this understanding correct?

- Am I allowed to modify errno in my own functions as well? I
would say yes, but am not sure.

- Assuming I may modify errno in my own functions, I guess it
would also be ok for me to set it to EOK on success to allow
someone to determine the success/failure of my function by
purely inspecting the return value (I would probably tend
to just return errno at the end of the function, so both
approaches would work). Is this true?

- I am assuming that errno is a global integer value. Is this
correct?

<OT>
And the last question leads me to the announced off-topic follow-up
question:

- if errno is implemented with a global variable, how can any
multi-threaded application (and I know that this is beyond
the C standard) such as a POSIX implementation support standard
functions that make use of errno?
- is there an obvious trick on how to implement errno differently
that I am missing?
- or can those functions still be used but errno may not be
evaluated safely?
- or does POSIX redefine the C standard library to not make
use of errno
- any other solution/situation I did not think of?
</OT>

Looking forward to enlightment
/urs
 
R

ranjmis

Urs said:
I have a question regarding errno. If I understand it correctly,
including <errno.h> allows me to check "errno" for error values
that some standard library functions may set.

This brings up some questions:

- As I understand it, most functions only set errno in an error
case. I take this to mean, that on success, errno is not
necessarily set to EOK and I would either need to set errno
to EOK before calling the function in question to determine
its outcome or I would need to check the return value first,
and then in an error case inspect errno to get more details.
Is this understanding correct?

At the start of program errno is set to zero then it can be modified by
any function
All the library functions that modify errno - set "errno" to non zero
int value
- Am I allowed to modify errno in my own functions as well? I
would say yes, but am not sure.

you can definitely modify errno
- Assuming I may modify errno in my own functions, I guess it
would also be ok for me to set it to EOK on success to allow
someone to determine the success/failure of my function by
purely inspecting the return value (I would probably tend
to just return errno at the end of the function, so both
approaches would work). Is this true?

actually errno has predefined meanings defined in errno.h and usually
we determine the kind of error by using functions :

void perror(const char *s);

So if EOK is defined then surely u can use it
- I am assuming that errno is a global integer value. Is this
correct?

yes its a global identifier
<OT>
And the last question leads me to the announced off-topic follow-up
question:

- if errno is implemented with a global variable, how can any
multi-threaded application (and I know that this is beyond
the C standard) such as a POSIX implementation support standard
functions that make use of errno?
- is there an obvious trick on how to implement errno differently
that I am missing?
- or can those functions still be used but errno may not be
evaluated safely?
- or does POSIX redefine the C standard library to not make
use of errno
- any other solution/situation I did not think of?
</OT>

may be we need to lock the portion of code where we are querying errno.
 
B

Ben Pfaff

Urs Beeli said:
- As I understand it, most functions only set errno in an error
case. I take this to mean, that on success, errno is not
necessarily set to EOK and I would either need to set errno
to EOK before calling the function in question to determine
its outcome or I would need to check the return value first,
and then in an error case inspect errno to get more details.
Is this understanding correct?

First, there's no (portable) constant EOK. An errno of 0
indicates a lack of error status.

Your questions are answered directly by the text of the standard:

The value of errno is zero at program startup, but is never
set to zero by any library function.170) The value of errno
may be set to nonzero by a library function call whether or
not there is an error, provided the use of errno is not
documented in the description of the function in this
International Standard.
- Am I allowed to modify errno in my own functions as well? I
would say yes, but am not sure.

Yes, you may modify errno.
- Assuming I may modify errno in my own functions, I guess it
would also be ok for me to set it to EOK on success to allow
someone to determine the success/failure of my function by
purely inspecting the return value (I would probably tend
to just return errno at the end of the function, so both
approaches would work). Is this true?

It would be more consistent with the standard library for your
function to only set errno if it has some kind of status to
report, typically an error. It would be quite unlike the
standard library for your function to set errno to 0; it would be
more normal for its caller to do so.

By the way, I'd only use errno for reporting errors if you're
passing along errors similar to those already reported by
standard library functions. Otherwise, it's probably better not
to use global data to report your error.
- I am assuming that errno is a global integer value. Is this
correct?

From a standard C perspective, yes. It's not necessarily a
variable, though; it could also be a macro.
<OT>
- if errno is implemented with a global variable, how can any
multi-threaded application (and I know that this is beyond
the C standard) such as a POSIX implementation support standard
functions that make use of errno?
- is there an obvious trick on how to implement errno differently
that I am missing?

It's only obvious once you've seen it:
#define errno (*__errno_function ())
where __errno_function() returns a thread-specific pointer.
 
J

Jordan Abel

<OT>
And the last question leads me to the announced off-topic follow-up
question:

- if errno is implemented with a global variable, how can any
multi-threaded application (and I know that this is beyond
the C standard) such as a POSIX implementation support standard
functions that make use of errno?

It could be a global variable in thread-local storage, or a macro
expanding to a call to a function that returns a location in such
storage.

My system's <errno.h>
int * __error(void);
#define errno (* __error())
 
L

loic-dev

It could be a global variable in thread-local storage, or a macro
expanding to a call to a function that returns a location in such
storage.

My system's <errno.h>
int * __error(void);
#define errno (* __error())

Yup. Exactly.
 
U

Urs Beeli

First, there's no (portable) constant EOK. An errno of 0
indicates a lack of error status.

Oops, I had not realised it wasn't standardised. Thanks for the
hint.
Your questions are answered directly by the text of the standard:

The value of errno is zero at program startup, but is never
set to zero by any library function.170) The value of errno
may be set to nonzero by a library function call whether or
not there is an error, provided the use of errno is not
documented in the description of the function in this
International Standard.
Thanks.

Yes, you may modify errno.


It would be more consistent with the standard library for your
function to only set errno if it has some kind of status to
report, typically an error. It would be quite unlike the
standard library for your function to set errno to 0; it would be
more normal for its caller to do so.

Thanks, that makes sense and I will map the behaviour of my functions
to those of the standard library.
By the way, I'd only use errno for reporting errors if you're
passing along errors similar to those already reported by
standard library functions. Otherwise, it's probably better not
to use global data to report your error.

Obviously :)
It's only obvious once you've seen it:
#define errno (*__errno_function ())
where __errno_function() returns a thread-specific pointer.

Ah, that makes sense. Thanks. I had been sure that there must be a trick
to make it work :)

Thanks, Ben and all the other posters, for your help.

Cheers
/urs
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top