File I/O - the universal I/O model
Universality of I/O
- One of the distinguishing features of the I/O model on UNIX systems is the concept of universality of I/O.
This means that the same system calls (
open()
,read()
,write()
,close()
, and so on) are used to perform I/O on all types of files, including devices. Thus, a program that employing these systems will work on any type of file.
- All system calls for performing I/O refer to open files using a
file descriptor
(a nonnegative integer). File descriptors are used to refer to all types of open files: pipes, FIFOs, sockets, terminals, devices and regular files. Each process has its own set of file descriptors.
Opening a file: open()
- A call to open() creates a new open file description, an entry in
the system-wide table of open files. The open file description
records the file offset and the file status flags (see below). A file descriptor is a non-negative integer that act as an abstract to handle file or I/O resources
0,1,2 are taken by
STDIN
,STDOUT
, andSTDERR
.
Explain
-
The file to be opened is identified by the
pathname
argument. Ifpathname
is asymbolic
link, it is dereferenced. -
The
flags
argument is a bitmask that specifies theaccess mode
for the file:Access mode Description Group O_RDONLY
Open for reading only File access mode flags O_WRONLY
Open for writing only File access mode flags O_RDWR
Open for reading and writing File access mode flags O_CLOEXEC
Set the close-on-exec flag (since Linux 2.6.23) File creation flags O_CREAT
Create file if it doesn’t already exist File creation flags O_DIRECT
File I/O bypasses buffer cache File creation flags O_DIRECTORY
Fail if pathname
is not a directoryFile creation flags O_EXCL
With O_CREAT
: create file exclusivelyFile creation flags O_LARGEFILE
Used on 32-bit systems to open large files File creation flags O_NOATIME
Don’t update file last access time on read()
(since Linux 2.6.8)File creation flags O_NOCTTY
Don’t let pathname
become the controlling terminalFile creation flags O_NOFOLLOW
Don’t dereference symbolic links File creation flags O_TRUNC
Truncate existing file to zero length File creation flags O_APPEND
Writes are always appended to end of file Open file status flags O_ASYNC
Generate a signal when I/O is possible Open file status flags O_DSYNC
Provide synchronized I/O data integerity (since Linux 2.6.33) Open file status flags O_NONBLOCK
Open in nonblocking mode Open file status flags O_SYNC
Make file write synchronous Open file status flags File access mode flags
: can be retrieved using thefcntl() F_GETFL
operationFile creation mode flags
: these flags control various aspects of the behavior of theopen()
call and options for subsequent I/O operations. They can’t be retrieved or changed.Open file status flags
: these flags can be retrieved and modified using thefcntl()
F_GETFL
andF_SETFL
operations
Errors handling
-
If an error occurs while trying to open the file,
open()
returns –1, anderrno
identifies the cause of the errorNAME Description EACCES The file permissions don’t allow the calling process to open the file in the mode specified by flags. Alternatively, because of directory permissions, the file could not be accessed, or the file did not exist and could not be created. EISDIR The specified file is a directory, and the caller attempted to open it for writing. This isn’t allowed. EMFILE The process resource limit on the number of open file descriptors has been reached ENFILE The system-wide limit on the number of open files has been reached. ENOENT The specified file doesn’t exist, and O_CREAT was not specified, or O_CREAT was specified, and one of the directories in pathname doesn’t exist or is a symbolic link pointing to a nonexistent pathname (a dangling link). EROFS The specified file is on a read-only file system and the caller tried to open it for writing. ETXTBSY The specified file is an executable file (a program) that is currently executing. It is not permitted to modify (i.e., open for writing) the executable file associated with a running program. (We must first terminate the program in order to be able to modify the executable file.)
Example
Reading from a file: read()
- This system call doesn’t place a terminating null byte at the end of the string.