File IO Stystem Calls
File IO Stystem Calls
Principles
File I/O System Calls
Overview
System Calls for I/O
● The focus of this lecture is the system calls used for performing file
I/O
● We introduce the concept of a file descriptor
● Then look at the system calls that constitute the so-called
universal I/O model
○ open and close a file
○ read and write data
● We focus on I/O on disk files
○ Much of the material covered here is relevant for other I/O,
since the same system calls are used for performing I/O
on all types of files, such as pipes and terminals
OS Abstractions
3
File descriptors
● Each process has its own set of file descriptors
● All system calls for performing I/O refer to open files using a file
descriptor
Program Status
Program Code
File descriptors
● Are (usually small) nonnegative integer
● File descriptors are used with all types of open files
○ Pipes
○ FIFOs
○ Sockets readme.txt prog.c prog.h
○ Terminals
○ Devices
○ Regular files Socket Pipe Directory Devices Link
Standard file descriptors
● The programs inherit copies of the shell’s file descriptors
● The shell normally operates with these three file descriptors always
open
● Use either the numbers (0, 1, or 2) or, preferably, the POSIX
standard names defined in <unistd.h>
Standard file descriptors
Note!
The FILENO forms are small integers referring to Linux file descriptors;
File I/O
● read() doesn’t place a terminating null byte at the end of the string
○ If a terminating null byte is required at the end of the input buffer, we must put it
there explicitly
○ Because the terminating null byte requires a byte of memory, the size of the
buffer must be at least one greater than the largest string we expect to read
Write
● On success, write() returns the number of bytes actually written
this may be less than count
○ For a disk file, possible reasons for such a partial write are that the disk was filled
or that the process resource limit on file sizes was reached
● This is the location in the file at which the next read() or write()
will commence
Offset =
0
H A P P Y B I R T H D A Y T O M E
Changing the File Offset: lseek()
read(fdin, buf, 5)
H A P P Y ? ? ? ? ?
Offset =
5
H A P P Y B I R T H D A Y T O M E
Changing the File Offset: lseek()
It’s not ‘\0’
read(fdin, buf, 5)
H A P P Y ? ? ? ? ?
Offset =
5
H A P P Y B I R T H D A Y T O M E
Changing the File Offset: lseek() (cont.)
● The lseek() system call adjusts the file offset of the open file
referred to by the file descriptor fd, according to the values
specified in offset and whence
Offset =
5
H A P P Y B I R T H D A Y T O M E
Changing the File Offset: lseek()
lseek(fdin, 9, SEEK_SET);
Offset =
9
H A P P Y B I R T H D A Y T O M E
Changing the File Offset: lseek()
lseek(fdin, 9, SEEK_CUR);
Offset =
14
H A P P Y B I R T H D A Y T O M E
Changing the File Offset: lseek()
Offset =
2
H A P P Y B I R T H D A Y T O M E
Changing the File Offset: lseek() (cont.)
Offset =
21
H A P P Y B I R T H D A Y T O M E
Changing the File Offset: lseek()
H A P P Y B I R T H D A Y T O M E
File descriptor table
● For each process, the kernel maintains a table of open file
descriptors
● Each entry in this table records information about a single file
descriptor, including: