Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!uunet!husc6!cmcl2!brl-adm!brl-smoke!gwyn
From: gwyn@brl-smoke.ARPA (Doug Gwyn )
Newsgroups: comp.lang.c
Subject: Re: stdio error detection
Message-ID: <6753@brl-smoke.ARPA>
Date: Fri, 27-Nov-87 21:49:37 EST
Article-I.D.: brl-smok.6753
Posted: Fri Nov 27 21:49:37 1987
Date-Received: Mon, 30-Nov-87 00:48:24 EST
References: <289@cresswell.quintus.UUCP> <6748@brl-smoke.ARPA> <290@cresswell.quintus.UUCP>
Organization: Ballistic Research Lab (BRL), APG, MD.
Lines: 48
Keywords: errno fclose fopen stdio errors

In article <290@cresswell.quintus.UUCP>, ok@quintus.UUCP (Richard A. O'Keefe) writes:
- In article <6748@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn) ... said:
- > ... if you assume that the stdio function failed because
- > some system call failed, it is fairly reliable.
- No way is it reliable.  (a) I have no way of telling whether a stdio
- function failed because some system call failed or for some other
- reason -- that is what I was ASKING for!  (b) There is nothing to stop
- a valid implementation of stdio calling some other system call after
- the failed one, and that undefines errno even if the later system call
- succeeds.

With the exception of fopen() failing because there are no statically-
allocated FILE structures left, and ungetc() beyond the available space
for pushback, (again assuming no bugs in the application code) the way
that stdio functions fail is for some system call to fail.  A system
call failure sets errno and practically nothing in the C library clears
errno, so it is "sticky".  Errno can be relied on to indicate the reason
for the most recent system call (or math routine) failure.  In the case
of stdio, this will be the low-level reason the stdio function failed.

- > In a UNIX environment, ENOMEM (or, less likely, EAGAIN) are the errno
- > codes for inability to obtain more memory for the process.  If malloc()
- > cannot obtain enough memory, one of these codes will be set in errno.
- In SunOS 3.2 the malloc() family is explicitly defined to set errno, and
- the different cases are clearly distinguished.  However, this is NOT in
- the SVID, and it is NOT in any System V manual I've checked.  POSIX
- (the IEEE 1003.1 standard) inherits malloc() from the C standard, which
- is silent on this point.

UNIX implementations of malloc() can fail to obtain needed space only if
an attempted sbrk() system call fails, and sbrk() failure sets one of the
errno values I indicated (BSD systems may have slightly different values).

Again, the key is to realize that eventually these functions make one
or more system calls in the process of servicing the request, and the
reason for failure will be recorded in errno, even though this isn't
advertised by the official interface definition.

- One of the things that bothers me about fclose() is this:
- 	suppose f is a valid pointer to an open output stdio stream,
- 	but that fclose(f) returns EOF -- perhaps because of a write
- 	error when flushing remaining buffered output, or perhaps
- 	because of an unlucky interrupt (check man 2 close).
- 	IS f CLOSED?

That depends on the implementation.  A quality implementation will make
sure that the OS channel (file descriptor, on UNIX) is deallocated by
fclose() no matter what happens during the final write().