[comp.lang.c] perror, yet again

peter@ficc.ferranti.com (Peter da Silva) (11/30/90)

In article <14603@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes about
code like:
> >    if ((fp[i]=fopen(file_name[i],"r+")) <= 0)
> >        perror("Error opening file");

To begin with <0 is a valid return value for fopen(), but aside from that:

> Please don't do this; on UNIX, perror() will report the reason for the last
> SYSTEM CALL failure, not the reason for failure of a library routine such as
> fopen().  Sometimes there is a close relation between these but at other
> times there is not, leading to such absurd diagnostics as "Error opening
> file: not a tty".

In every case where I've got the source to a program and have figured out
where something like that came from it's been one of the two following
cases:

	if(!(fp = fopen(...))) {
		fprintf(stderr, "%s: ", argv[0]);
		perror(...);
	}

(where the fprintf stomped on errno when deciding what buffering to do) or:

	if(!(fp = fopen(...))) goto cleanup;
	if(!something...else) goto cleanup;
	...
cleanup:
	perror();

(where the error might not have had anything to do with stdio). In general
the simple code:

	if(!(fp = fopen(...))) {
		perror(...);
		...
	}

does a perfectly adequate job of printing a usable error message. It would
be nicer to have ferror(fp) return an error number suitable for feeding
to strerror(), but in the meantime it's better than nothing.
-- 
Peter da Silva.   `-_-'
+1 713 274 5180.   'U`
peter@ferranti.com 

andrew@motto.UUCP (Andrew Walduck) (12/05/90)

Peter da Siva writes:
>(where the error might not have had anything to do with stdio). In general
>the simple code:
>
>	if(!(fp = fopen(...))) {
>		perror(...);
>		...
>	}
>does a perfectly adequate job of printing a usable error message. It would
>be nicer to have ferror(fp) return an error number suitable for feeding
>to strerror(), but in the meantime it's better than nothing.
>-- 
>Peter da Silva.   `-_-'
>+1 713 274 5180.   'U`
>peter@ferranti.com 

Actually, a more correct (ANSI) implementation would be:

	if((fp = fopen(...)) == NULL) {
		perror(...);
		...
	}

as fopen returns NULL upon failure...and NULL is NOT necessarily zero,
which is assumed in your code above.  

Andrew
 ------------------------------------------------------
| Andrew Walduck | andrew@motto.UUCP | Motorola Canada |
 ------------------------------------------------------