fclose(3S) fclose(3S) NAME fclose, fflush - close or flush a stream SYNOPSIS #include <stdio.h> int fclose (FILE *stream); int fflush (FILE *stream); DESCRIPTION fclose causes any buffered data waiting to be written for the named stream [see intro(3)] to be written out, and the stream to be closed. If the underlying file pointer is not already at end of file, and the file is one capable of seeking, the file pointer is adjusted so that the next operation on the open file pointer deals with the byte after the last one read from or written to the file being closed. If stream points to an output stream or an update stream on which the most recent operation was not input, fflush causes any buffered data waiting to be written for the named stream to be written to that file. Any unread data buffered in stream is discarded. The stream remains open. When calling fflush, if stream is a null pointer, all files open for writing only and all files open for update whose last operation was a write are flushed. fflush(NULL) is performed automatically on calling exit. NOTES If two streams point to the same underlying file descriptor, the semantics associated with their use is complex. They are described in detail in the POSIX90 1003.1 section 8.2.3. The most common way for an unsuspecting application writer to wander into this situation is via fork(2). fork of course replicates the process, including any stdio buffers, while both the parent's and child's underlying file descriptor share a common file offset pointer. This means that actions performed in one process may affect the other. Consider the following: Parent: fp = fopen("foo", "r"); fread(buf, 100, 1, fp); fork(); wait(NULL); fread(buf, BUFSIZ+1, 1, fp); Child: exit(0); The parent reads the first 100 bytes which really reads BUFSIZ bytes into an internal stream buffer. The underlying file descriptor has its file offset set to BUFSIZ. After the fork, the parent waits for the child. The child calls fclose which causes the underlying file descriptor to be synchronized with stream. In this case that means that an lseek on the underlying file descriptor will be performed to set the file offset back to 100. Since the file descriptor offset pointer is shared between parent and child, the parent's file descriptor now points at offset 100. When the parent continues reading and finishes the first buffer, a second buffer will be read. The parent is assuming that the file offset is still at BUFSIZ but the child's actions have changed it to 100. The parent will get the incorrect data. The solution to this to either not have the child call fclose or to synchronize the file descriptor with stream before calling fork. Synchronization is done by calling fflush(fp). Note that calling fflush(NULL) will not suffice since it doesn't effect read only streams. SEE ALSO close(2), exit(2), intro(3), fopen(3S), setbuf(3S), stdio(3S) DIAGNOSTICS On successful completion these functions return a value of zero. Otherwise EOF is returned. For fflush(NULL), an error is returned if any files encounter an error. For fclose, EOF is returned if stream is NULL, or stream is not active, or there was an error when flushing buffered writes, or there was an error closing the underlying file descriptor. Page 2