returning error from main()

I

Ian Collins

jacob said:
Interesting. POSIX manages to do exactly that, but somehow
the C standard could not manage doing it.

POSIX specifies exactly the type of errors that can be thrown by
fopen!

One reason why I use POSIX as my "portable" standard.
 
R

Richard Tobin

POSIX specifies exactly the type of errors that can be thrown by
fopen!

Several of them are specific to unix. Presumably Microsoft Windows
has some reasons for fopen() failing that unix doesn't have. And so
on for other operating systems. It would not be approriate for C to
try to list all the kinds of errors that could occur. But I can't see
why it doesn't specify that errno is set to a system-dependent value.

-- Richard
 
J

jacob navia

Ian said:
One reason why I use POSIX as my "portable" standard.

The C standard could use the same interface, and in system
where the error makes no sense, it would be just ignored!

All those errors are just #defines that would take no
implementation effort and only be used in the systems
where those errors are supported.
 
E

Eric Sosman

jacob navia wrote On 09/24/07 07:04,:
The C standard could use the same interface, and in system
where the error makes no sense, it would be just ignored!

What happens on a system where fopen() can fail for
reasons POSIX doesn't enumerate? I have used a system
where a file specification could (optionally) include an
account name and password; the attempt to open could fail
because of bad credentials. You might, with a stretch,
translate this to POSIX' EACCESS, but that's really not
how EACCESS is described.

File specifications on that same system could also
include network node names, and an open could fail because
of networking issues, permanent or transient. POSIX defines
errno values that describe network problems, but I don't
see any of them among the list that fopen() is allowed to
produce. So, what errno code should be delivered if a
network problem disrupts the open?

Still on the same system: An open could fail because
of invalid combinations of things like "record formats"
(specified in the second argument). Since POSIX has no
notion of "record format," POSIX defines no error codes
to describe problems with them; what code ought fopen()
to produce for this kind of failure?

What POSIX error code corresponds to picking "Cancel"
on the "Retry, Cancel, Abort?" dialog?
All those errors are just #defines that would take no
implementation effort and only be used in the systems
where those errors are supported.

If you try to enumerate all the possible reasons fopen()
could fail on all possible systems, you will find yourself
writing a very large number of #define's ... Also, the
resulting set will probably contain ambiguities.

POSIX is an adequate description of a certain class of
systems. It is not a description of all systems where C
runs, nor does it describe a superset of those systems.
Some systems just don't fall fully in the POSIX shadow.
 
L

lawrence.jones

Charlie Gordon said:
What exactly was the rationale for not specifying it in the Standard ?

When the original C standard was written, very few (if any)
implementations *reliably* set errno when fopen() failed (many of them
set it most, but not all, of the time and most of them set it under some
conditions when fopen succeeded). It wasn't existing practice, so it
wasn't standardized.

Since then, the world has changed (thanks in part to POSIX) and most
implementations do now reliably set it, so it could have been changed in
C99, but no one proposed it as far as I can recall.

-Larry Jones

Yep, we'd probably be dead by now if it wasn't for Twinkies. -- Calvin
 
L

lawrence.jones

Ben Bacarisse said:
More specifically, if one does the recommended errno = 0; prior to the
call, are there really implementations of fopen that return NULL and
set errno to some unhelpful value?

There certainly were when the original C standard was written. In fact,
most implementations would do exactly that in some cases (that were,
thankfully, not very common). Since POSIX requires fopen() to reliably
set errno, I suspect that it no longer occurs.

-Larry Jones

It seems like once people grow up, they have no idea what's cool. -- Calvin
 
L

lawrence.jones

jacob navia said:
Interesting. POSIX manages to do exactly that, but somehow
the C standard could not manage doing it.

POSIX specifies exactly the type of errors that can be thrown by
fopen!

That's because POSIX is an OS standard and thus has a priori knowledge
of all the OS-specific details that the C standard does not.

-Larry Jones

My dreams are getting way too literal. -- Calvin
 
C

Charlie Gordon

Eric Sosman said:
jacob navia wrote On 09/24/07 07:04,:

What happens on a system where fopen() can fail for
reasons POSIX doesn't enumerate? I have used a system
where a file specification could (optionally) include an
account name and password; the attempt to open could fail
because of bad credentials. You might, with a stretch,
translate this to POSIX' EACCESS, but that's really not
how EACCESS is described.

File specifications on that same system could also
include network node names, and an open could fail because
of networking issues, permanent or transient. POSIX defines
errno values that describe network problems, but I don't
see any of them among the list that fopen() is allowed to
produce. So, what errno code should be delivered if a
network problem disrupts the open?

Still on the same system: An open could fail because
of invalid combinations of things like "record formats"
(specified in the second argument). Since POSIX has no
notion of "record format," POSIX defines no error codes
to describe problems with them; what code ought fopen()
to produce for this kind of failure?

What POSIX error code corresponds to picking "Cancel"
on the "Retry, Cancel, Abort?" dialog?


If you try to enumerate all the possible reasons fopen()
could fail on all possible systems, you will find yourself
writing a very large number of #define's ... Also, the
resulting set will probably contain ambiguities.

POSIX is an adequate description of a certain class of
systems. It is not a description of all systems where C
runs, nor does it describe a superset of those systems.
Some systems just don't fall fully in the POSIX shadow.

I agree with you.
I still think the Standard should mandate the implementation to store an
implementation defined value in errno upon failure by fopen to open the
stream; an informative error message would be produced by strerror(errno).
 
A

Al Balmer

The real answer is to implement safe pointers, which consist of three memory
addresses, the pointer itself and the bounds of the object it points to.
It means a slower language, but there just isn't another way I know of of
preventing buffer overruns.

I know another way - just don't write code that's susceptible to
buffer overruns :)
 
J

jacob navia

Eric said:
jacob navia wrote On 09/24/07 07:04,:

What happens on a system where fopen() can fail for
reasons POSIX doesn't enumerate? I have used a system
where a file specification could (optionally) include an
account name and password; the attempt to open could fail
because of bad credentials. You might, with a stretch,
translate this to POSIX' EACCESS, but that's really not
how EACCESS is described.

Why not?
It is an access error.
File specifications on that same system could also
include network node names, and an open could fail because
of networking issues, permanent or transient.

ENXIO could be used. The C specification could simplify
POSIX and use only 4-5 different things, without
forbidding other extended error reporting.

POSIX defines
errno values that describe network problems, but I don't
see any of them among the list that fopen() is allowed to
produce. So, what errno code should be delivered if a
network problem disrupts the open?

This is a hardware failure and could be just Error I/O
or similar.
Still on the same system: An open could fail because
of invalid combinations of things like "record formats"
(specified in the second argument). Since POSIX has no
notion of "record format," POSIX defines no error codes
to describe problems with them; what code ought fopen()
to produce for this kind of failure?

Posix says:
EINVAL: The "mode" argument is invalid (second argument)
What POSIX error code corresponds to picking "Cancel"
on the "Retry, Cancel, Abort?" dialog?

ENXIO: Input/Output error
In any case the Retry option is not seen by fopen() and the
abort bypasses it.

If you try to enumerate all the possible reasons fopen()
could fail on all possible systems, you will find yourself
writing a very large number of #define's ... Also, the
resulting set will probably contain ambiguities.

No. You misunderstand. C would define just 4 or 5 errors
with
o hardware error,
o not found error
o Access permissions errors
o No more memory or max number of files reached
o Argument error: file name NULL, or invalid mode string

An implementation could extend those errors with all the
detail they care to give.

Or an implementation could ALWAYS return not found, even
if it was some other kind of error.

The only thing that would change is that programs could
do PORTABLE error checking for MOST errors!
 
E

Eric Sosman

Charlie Gordon wrote On 09/24/07 11:34,:
[...]
I still think the Standard should mandate the implementation to store an
implementation defined value in errno upon failure by fopen to open the
stream; an informative error message would be produced by strerror(errno).

I'd go further, and hope/require that *any* library
function set errno in the event of a (reported) failure.
This should not be a big burden on implementations, since
the fallback of reporting EMISC "something went wrong" is
always available; the QoI, though low, would be marginally
higher than just doing nothing. It's somehow dispiriting
to see "malloc failed: no error" on the console ...

One possible glitch in the "should not" above concerns
the expansion of library functions in-line, possibly with
assistance from macros. It may not be easy to control the
on-error behavior of a machine instruction or sequence
without introducing penalties. However, such concerns did
not deter the Standard from specifying how sqrt() must deal
with negative arguments, regardless of what the hardware's
SQRT instruction might or might not do with them.

The errno mechanism is less than wonderful, but as was
once said of the late Gerald Ford, "He's the only Vice
President we've got." It seems to me that wider use of
errno would do no harm and some good, and since no plausible
alternative error-reporting mechanism has been suggested
I wish the Standard would make more use of what's already
there.
 
R

Richard Harter

jacob navia wrote On 09/24/07 07:04,:

What happens on a system where fopen() can fail for
reasons POSIX doesn't enumerate? I have used a system
where a file specification could (optionally) include an
account name and password; the attempt to open could fail
because of bad credentials. You might, with a stretch,
translate this to POSIX' EACCESS, but that's really not
how EACCESS is described.

[snip litany of possible differences]

The obvious thing to do is have a general error code in addition
to the ones imported from posix. The general code would cover
all errors not otherwise classified. Do you have a problem with
that?


Richard Harter, (e-mail address removed)
http://home.tiac.net/~cri, http://www.varinoma.com
But the rhetoric of holistic harmony can generate into a kind of
dotty, Prince Charles-style mysticism. -- Richard Dawkins
 
?

=?iso-2022-kr?q?=1B=24=29CHarald_van_D=0E=29=26=0F

What happens on a system where fopen() can fail for
reasons POSIX doesn't enumerate? I have used a system where a file
specification could (optionally) include an account name and password;
the attempt to open could fail because of bad credentials. You might,
with a stretch, translate this to POSIX' EACCESS, but that's really not
how EACCESS is described.

[snip litany of possible differences]

The obvious thing to do is have a general error code in addition to the
ones imported from posix. The general code would cover all errors not
otherwise classified. Do you have a problem with that?

I do. If fopen can fail for other reasons than specified by POSIX, the
implementation should define additional error codes properly. There's no
point in using something like EIDUNNO, which tells you nothing more than
fopen's NULL return value, when an implementation-specific EBADCRED could
be defined just as easily. It would then make sure a decent message can
get printed by strerror. (As an aside, I don't see the problem with
EACCES for this specific error, but I do agree with some of the other
snipped examples.)
 
R

Richard Harter

What happens on a system where fopen() can fail for
reasons POSIX doesn't enumerate? I have used a system where a file
specification could (optionally) include an account name and password;
the attempt to open could fail because of bad credentials. You might,
with a stretch, translate this to POSIX' EACCESS, but that's really not
how EACCESS is described.

[snip litany of possible differences]

The obvious thing to do is have a general error code in addition to the
ones imported from posix. The general code would cover all errors not
otherwise classified. Do you have a problem with that?

I do. If fopen can fail for other reasons than specified by POSIX, the
implementation should define additional error codes properly. There's no
point in using something like EIDUNNO, which tells you nothing more than
fopen's NULL return value, when an implementation-specific EBADCRED could
be defined just as easily. It would then make sure a decent message can
get printed by strerror. (As an aside, I don't see the problem with
EACCES for this specific error, but I do agree with some of the other
snipped examples.)

I don't quite understand your objection. What we are talking
about are the error codes (that should be) required by the
standard. Clearly the standard cannot specify codes for all
possible errors in all possible implementations. What it can do
is specify that there are codes for the commonest errors.

Adding codes for all possible errors is up to the implementation.
However that is necessarily non-portable.



Richard Harter, (e-mail address removed)
http://home.tiac.net/~cri, http://www.varinoma.com
But the rhetoric of holistic harmony can generate into a kind of
dotty, Prince Charles-style mysticism. -- Richard Dawkins
 
J

jacob navia

Richard Harter wrote:
[snip]
I don't quite understand your objection. What we are talking
about are the error codes (that should be) required by the
standard. Clearly the standard cannot specify codes for all
possible errors in all possible implementations. What it can do
is specify that there are codes for the commonest errors.

Adding codes for all possible errors is up to the implementation.
However that is necessarily non-portable.

This is exactly what I am proposing. This would allow to write
PORTABLE programs that would be able to do some error analysis!

The terrible situation now, i.e. developing code for EACH
combination of OS + compiler is so difficult to implement that
it makes portable error analysis IMPOSSIBLE!!!
 
T

Tor Rustad

Chris said:
(Note, as an aside to Jacob and maybe others: I said *best*, not
*only*, here.)

Doing the "Right Thing", may not win over "worse is better" design.

Well, POSIX, more generally. As Rob Pike put it back in 1991:
"Not only is UNIX dead, it's starting to smell really bad."
(Overstatement for effect, perhaps, but still... :) )

It's hard to predict, particularly about the future. :)

Anyway, Pike has been proved wrong. I must admit, I didn't see Ubuntu &
friends arriving in 1991 either. The "failure" of Plan 9 and success of
Linux, didn't exactly make Pike positive towards Linux, BSD, ... and the
open source community.

Yes. It is not at all clear to me why ISO did not at least pick
this up. This is, I think, a smaller yet even more important change
than most of the various "_r" re-entrant interfaces that are also
in POSIX, but not ISO C.

Agreed, as long as ISO C don't specify threads and the current (lack of)
signal definition exist, the "_r" functions is better left to POSIX.
 
K

Keith Thompson

There certainly were when the original C standard was written. In fact,
most implementations would do exactly that in some cases (that were,
thankfully, not very common). Since POSIX requires fopen() to reliably
set errno, I suspect that it no longer occurs.

It could occur under implementations that support standard C but don't
claim conformance to POSIX. But I wonder how many hosted C
implementations these days don't at least try to support POSIX.
 
K

Keith Thompson

jacob navia said:
Interesting. POSIX manages to do exactly that, but somehow
the C standard could not manage doing it.

POSIX specifies exactly the type of errors that can be thrown by
fopen!

POSIX doesn't let you write a function which can absolutely tell you
if a file exists.

Yes, POSIX requires fopen() to set errno on failure, and standard C
does not.

I agree that it would be better if the C standard required fopen() to
set errno to some meaningful value on failure. In most cases, this
doesn't help much in terms of the behavior of programs; it lets a
program display a meaningful error message, but the program's response
to a failure is likely to be the same whatever the cause of the error:
display or log an error message and move on.

I would even be nice if *all* standard functions that are able to
report failure were required to set errno to some meaningful value
when a failure occurs.

But keep in mind that most of us here in comp.lang.c are users, not
implementers or committee members. We're stuck with what the standard
specifies, or, at best, with what the implementations we use happen to
support. If you want the standard to require the setting of errno in
more contexts, then you should post a suggestion to comp.std.c. But
even if everyone agrees, nothing is likely to happen any time soon,
since there are no immediate plans for a new standard (and *please*
don't waste time complaining to us about that).
 

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,774
Messages
2,569,596
Members
45,128
Latest member
ElwoodPhil
Top