Re: [Libclc-developers] Re: libclc questions
Status: Planning
Brought to you by:
augestad
|
From: Michael B.A. <mb...@io...> - 2003-03-17 21:20:24
|
On Mon, 17 Mar 2003 12:33:52 +0100
Hallvard B Furuseth <h.b...@us...> wrote:
>
> > Same goes for probably every other ISO function you'll use.
>
> fgetpos() can return ESPIPE (file descriptor is a pipe, FIFO, or socket)
> on my system (Solaris). Do you think that can happen on systems that do
> not support pipes?
Then they just won't return ESPIPE. I'm not sure I understand your
point. You can't squash the errno code. There are about 15 error codes
that can be returned by open(2) alone which means fopen can return quite
a few more. If an error occurs calling a libc function you should just
return -1 or NULL or whatever and leave errno alone.
> > You're introducing a technically unncessary level of indirection that
> > contributes to an overall non-standard experience for the sake of a
> > standard. Why are you going to make 99.9999% of the users deal with
> > two different namespaces of error codes for some imaginary platform
> > that doesn't exist? Following the letter of the law for this is just
> > being pedantic.
>
> So far, we don't know if we'll be using any CLC_E* error codes. There
> is little point in setting errno = CLC_ENOMEM in a function which can
> only return one type of error, for example. Then all the user needs it
> to test whether or not an error happened.
Well you should still set errno to be consistent. If a function returns
an error and the practice has been to check errno you should set it even
if there is only one possible errror code just to be consistent.
> The main point so far is that we want a standardized way which functions
> can return error conditions if they want to. We could have said that
> such functions return an integer error code. We chose not to; we
> preferred to reuse the errno mechanism which already exists. Given
> that, we _had_ to open for the possibility that functions may need to
> set errno to something which does not exist in any errno.h.
The common E* identifiers are available with all significant libc
systems. And if they are not there is likely a reason that you should
not try to second guess. Even minimalistic non-POSIX system will have
all the codes you would need for linked lists, configuration file modules
and other such ANSI stuff.
To tell you the truth these days I am beginning to wonder about the
usage of errno at all. POSIX.1 requires that errno is:
extern int errno;
This is not safe. Fortunately most implementations follow ISO C which
permits errno to be a macro that evaluates to a modifiable lvalue. This
is reentrant but it still doesn't provide a clean mechanism to communicate
error codes within a multithreaded program.
There are two kernel programming idioms that you might also consider. I'm
not advocating anything here I'm just providing you with options. The
first is to always return the error code on the stack like:
if (getit(&ans)) == -1) {
return -ENOENT;
}
If a pointer is normally returned you use ERR_PTR, PTR_ERR, and IS_ERR
macros as described here:
http://www.win.tue.nl/~aeb/linux/lk/lk-2.html#ss2.7.3
As long as we're on the topic of error codes I have another
suggestion. Most library functions return -1 to indicate an error. For
a while my personal library of stuff used 0 to indicate an error occured
whereas 1 meant success. I recenty changed all of my functions to return
-1 on error. Notices some multibyte string functions may also return
-2 to indicate a different error although I don't know if any ISO C
functions do this.
I also feel it is important never to design an interface that provides
no way to return an error indication. This can be easy to do when
creating a function that returns a pointer to something but NULL is
an appropriate value for the pointer (e.g. retrieving something from a
table perhaps). But this leaves no way to indicate to the caller that
an error occured. It might be better to pass a pointer to the pointer
in this case. Or you could employ the kernel idiom I mentioned.
Finally, I know this is obvious but a library function should never set
errno to 0.
Mike
--
A program should be written to model the concepts of the task it
performs rather than the physical world or a process because this
maximizes the potential for it to be applied to tasks that are
conceptually similar and, more important, to tasks that have not
yet been conceived.
|