fopen, fclose
Function Prototype
FILE *fopen(const char *pathname, const char *type);
FILE *freopen(const char *pathname, const char *type, FILE *fp);
FILE *fdopen(int filedes, const char *type);
int fileno(FILE *fp);
int fclose(FILE *fp);All of these functions above are function calls and not system call
fopen
What it does?
- Calls
open()system call to obtain file descriptor - Allocate FILE object
- Return FILE pointer
We don't allocate buffer right when we call
fopen. The kernel only allocate buffer when we actually need it, i.e., the first time we do buffer I/O
type
| Restriction | r | w | a | r+ | w+ | a+ |
|---|---|---|---|---|---|---|
| file must already exist | • | • | ||||
| previous contents of file discarded | • | • | ||||
| stream can be read | • | • | • | • | ||
| stream can be written | • | • | • | • | • | |
| stream can be written only at end | • | • |
freopen
When pathname is specified
- Flush and close the original file
- Open the new file specified by pathname
- Reuse the same FILE object (same pointer)
When pathname is NULL
- Flush the buffer
- Modify the existing file descriptor’s access mode (using
fcntl, does NOT close/open) - Keep the same file and same FILE object
The FILE object and buffer memory are reused, but buffer contents are flushed before reopening
Mode Restrictions
- Read-only streams → can only reopen for reading
- Write-only streams → can only reopen for writing
- Read/write streams → can reopen in any mode
fdopen
The fdopen function call associates a FILE stream with an existing file descriptor, allowing us to use standard I/O function (like fprintf, fgets) on that descriptor
fdopenconnects a user space FILE object and corresponding buffer to file descriptor
fileno
Return file descriptor of this FILE object
fclose
Behavior
- Flush buffered output
- Discard buffered input
- All I/O streams are closed after the process exits
Warning
- If you use
setbuforsetvbufto allocate buffer, then this buffer must remain valid when you callfclose. This is becausefclosewill flush buffer, so if buffer is invalid thenfclosewill crash - For example, when a function returns, its local memory will be destroyed. This means the FILE pointer associated with local memory will be invalid
#define DATAFILE "datafile"
FILE *
open_data(void)
{
FILE *fp;
char databuf[BUFSIZ]; /* setvbuf makes this the stdio buffer */
if ((fp = fopen(DATAFILE, "r")) == NULL)
return(NULL);
if (setvbuf(fp, databuf, _IOFBF, BUFSIZ) != 0)
return(NULL);
return(fp); /* error */
}