Algorithms of Library I/O Functions in Unix/Linux

1. Algorithm of fread

The algorithm of fread() is as follows:

  • On the first call to fread(), the FILE structure’s buffer is empty. fread() uses the saved file descriptor fd to issue a

n = read(fd, fbuffer, BLKSIZE);

system call to fill the internal fbuf[ ] with a block of data. Then, it initializes fbuf[ ]’s pointers, counters and status variables to indicate that there is a block of data in the internal buffer. It then tries to satisfy the fread() call from the internal buffer by copying data to the program’s buffer area. If the internal buffer does not have enough data, it issues additional read() system call to fill the internal buffer, transfer data from the internal buffer to the program buffer, until the needed number of bytes is satisfied (or the file has no more data). After copying data to the program’s buffer area, it updates the internal buffer’s pointers, counters, etc. making it ready for next fread() request. It then returns the actual number of data objects read.

  • On each subsequent call to fread(), it tries to satisfy the call from the FILE structure’s internal buffer. It issues a read() system call to refill the internal buffer whenever the buffer becomes empty. Thus, fread() accepts calls from user program on one side and issues read() system calls to the OS kernel on the other. Except for the read() system calls, all processing of fread() are performed inside the user mode image. It enters the OS kernel only when needed and it does so in a way that matches the file system for best efficiency. It provides automatic buffering mechanism so that user programs do not have to worry about such detailed operations.

2. Algorithm of fwrite

The algorithm of fwrite() is similar to that of fread() except for the data transfer direction. Initially the FILE structure’s internal buffer is empty. On each call to fwrite(), it writes data to the internal buffer, and adjusts the buffer’s pointers, counters and status variable to keep track of the number of bytes in the buffer. If the buffer becomes full, it issues a write() system call to write the entire buffer to the OS kernel.

3. Algorithm of fclose

fclose() first flushes the local buffer of the FILE stream if the file was opened for WRITE. Then it issues a close(fd) system call to close the file descriptor in the FILE structure. Finally it frees the FILE structure and resets the FILE pointer to NULL.

Source: Wang K.C. (2018), Systems Programming in Unix/Linux, Springer; 1st ed. 2018 edition.

Leave a Reply

Your email address will not be published. Required fields are marked *