Unit 1 - File IO Flashcards
What are File Descriptors
To the kernel, all open files are referred to by file descriptors. A file descriptor is a
non-negative integer. When we open an existing file or create a new file, the kernel
returns a file descriptor to the process. When we want to read or write a file, we
identify the file with the file descriptor that was returned by open or creat as an
argument to either read or write.
File Descriptors
0 -> ?
1 -> ?
2 -> ?
UNIX System shells associate
file descriptor 0 with the standard input of a process, file descriptor 1 with the standard output
file descriptor 2 with the standard error.
Purpose of open and openat Functions
A file is opened or created by calling either the open function or the openat function.
Syntax of open and openat functions
#include int open(const char *path, int oflag, ... /* mode_t mode */ ); int openat(int fd, const char *path, int oflag, ... /* mode_t mode */ ); Both return: file descriptor if OK, −1 on error
Explain “path” parameter in open function
The path parameter is the name of the file to open or create.
Explain “oflag” parameter in open function
This argument is formed by ORing together one or more of the following constants from the header: O_RDONLY Open for reading only. O_WRONLY Open for writing only. O_RDWR Open for reading and writing.
Optional contraints
O_APPEND Append to the end of file on each write.
O_CREAT Create the file if it doesn’t exist. This option requires a third argument to the open function, the mode, which specifies the access permission bits of the new file.
O_EXCL Generate an error if O_CREAT is also specified and the file already exists.
O_TRUNC If the file exists and if it is successfully opened for either write-only or read–write, truncate its
length to 0.
O_NOCTTY If the pathname refers to a terminal device, do not allocate the device as the controlling terminal for this process.
O_NONBLOCK : If the pathname refers to a FIFO, a block special file, or a character special file, this option sets the non blocking mode for both the opening of the file and subsequent I/O.
Syntax and purpose of creat Function
new file can be created by calling the creat function.
#include int creat(const char *path, mode_t mode);
Returns: file descriptor opened for write-only if OK, −1 on error
that this function is equivalent to
open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
Syntax and purpose of close Function
An open file is closed by calling the close function. #include int close(int fd);
Returns: 0 if OK, −1 on error
Closing a file also releases any record locks that the process may have on the file. When a process terminates, all of its open files are closed automatically by thekernel.
Syntax and purpose of lseek function
Every open file has an associated ‘‘current file offset,’’ normally a non-negative integer that measures the number of bytes from the beginning of the file. Read and write operations normally start at the current file offset and cause the offset to be incremented by the number of bytes read or written. By default, this offset is initialized to 0 when a file is opened, unless the O_APPEND option is specified.
An open file’s offset can be set explicitly by calling lseek. #include off_t lseek(int fd, off_t offset, int whence);
Returns: new file offset if OK, −1 on error
lseek only records the current file offset within the kernel—it does not cause any I/O to take place.
This offset is then used by the next read or write operation.
lseek is defined in unistd.h
Explain “whence” parameter in lseek function
If whence is SEEK_SET, the file’s offset is set to offset bytes from the beginning of the file.
If whence is SEEK_CUR, the file’s offset is set to its current value plus the offset.
If whence is SEEK_END, the file’s offset is set to the size of the file plus the offset.
Syntax and purpose of read function
Data is read from an open file with the read function. #include ssize_t read(int fd, void *buf, size_t nbytes);
Returns: number of bytes read, 0 if end of file, −1 on error
If the read is successful, the number of bytes read is returned. If the end of file is encountered, 0 is returned.
Syntax and purpose of write function
#include ssize_t write(int fd, const void *buf, size_t nbytes);
Returns: number of bytes written if OK, −1 on error
For a regular file, the write operation starts at the file’s current offset. If the
O_APPEND option was specified when the file was opened, the file’s offset is set to the
current end of file before each write operation. After a successful write, the file’s offset
is incremented by the number of bytes actually written.
Syntax and purpose of pread function
Atomic functions
#include ssize_t pread(int fd, void *buf, size_t nbytes, off_t offset); Returns: number of bytes read, 0 if end of file, −1 on error
ssize_t pwrite(int fd, const void *buf, size_t nbytes, off_t offset); Returns: number of bytes written if OK, −1 on error
Calling pread, pwrite is equivalent to calling lseek followed by a call to read/write, with the
following exceptions.
• There is no way to interrupt the two operations that occur when we call pread.
• The current file offset is not updated.
Syntax and purpose of dup and dup2 functions
An existing file descriptor is duplicated by either of the following functions: #include int dup(int fd); int dup2(int fd, int fd2);
With dup2, we specify the value of the new descriptor with the fd2 argument. If fd2 is already open, it is first closed. If fd equals fd2, then dup2 returns fd2 without closing it.
Equivalent function calls of dup and dup2 using fctnl
The call
dup(filedes);
is equivalent to
fcntl(filedes, F_DUPFD, 0);
Similarly, the call dup2(filedes, filedes2); is equivalent to close(filedes2); fcntl(filedes, F_DUPFD, filedes2);
Note: dup2 is an atomic operation, whereas the alternate form involves two function calls (close and the fcntl)