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?

  1. Calls open() system call to obtain file descriptor
  2. Allocate FILE object
  3. 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

Restrictionrwar+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

  1. Flush and close the original file
  2. Open the new file specified by pathname
  3. Reuse the same FILE object (same pointer)

When pathname is NULL

  1. Flush the buffer
  2. Modify the existing file descriptor’s access mode (using fcntl, does NOT close/open)
  3. 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

fdopen connects 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 setbuf or setvbuf to allocate buffer, then this buffer must remain valid when you call fclose. This is because fclose will flush buffer, so if buffer is invalid then fclose will 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 */
}