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().