Chapter 2: I don't know much about it. I think it's not that important.
3.1. Introduction
Most file I/o on a UNIX system can be saved med using only five functions:
Open,Read,Write,Lseek, AndClose. We then examine the effect of various Buffer Sizes on
ReadAndWriteFunctions. The term unbuffered means that each
ReadOrWriteInvokes a system call in the kernel. These unbuffered I/O functions are not part of ISO C, but are part of posix.1 and the single UNIX specification.
3.2. file descriptors
By convention, UNIX system shells associate file descriptor 0 with the standard input of a process, file descriptor 1 with the standard output, and file descriptor 2 with the standard error. it is not a feature of the UNIX kernel. nevertheless, except applications
Wocould break if these associations weren't followed.Stdin_fileno,Stdout_fileno, And
Stderr_fileno. These constants are defined in<Unistd. h>Header. file descriptors range from 0 through
Open_max.
3.3.OpenFunction
# Include <fcntl. h>
Int open (const char * pathname, int
Oflag,.../* mode_t
Mode */);
The third argument is used only when a new file is being create. We'll show how to specify
Mode in
Section 4.5
Oflag:
O_rdonlyAs 0,O_wronlyAs 1, andO_rdwrAs 2.
Only one
O_appendO_creat o_excl (with o_creat) o_trunc (truncate its length to 0) o_noctty (?) O_nonblock (?)
O_rsync (single read) o_sync o_dsync (similiar write synchronized)
File status flag |
Description |
O_rdonly |
Open for reading only |
O_wronly |
Open for writing only |
O_rdwr |
Open for reading and writing |
O_append |
Append on each write |
O_nonblock |
Nonblocking Mode |
O_sync |
Wait for writes to complete (data and attributes) |
O_dsync |
Wait for writes to complete (data only) |
O_rsync |
Synchronize reads and writes |
O_fsync |
Wait for writes to complete (FreeBSD and Mac OS X only) |
O_async |
Asynchronous I/O (FreeBSD and Mac OS X only) |
Filename and pathname truncation (when file name is longer than name_max)
3.4. CreatFunction
#include <fcntl.h> int creat(const char *pathname, mode_t mode);
This function is equivalent
Open (pathname, o_wronly | o_creat | o_trunc,
Mode );
We'll show how to specify mode in
Section 4.5
3.5. CloseFunctionan open file is closed by calling
CloseFunction. # include <unistd. h>
int close(int filedes);
When a process terminates, all of its open files are closed automatically by the kernel. Many programs take advantage of this fact and don't explicitly close open files.
3.6.LseekFunction
#include <unistd.h> off_t lseek(int filedes, off_t offset, int whence);
whence:
SEEK_SET SEEK_CUR SEEK_END
If the file descriptor refers to a pipe, FIFO, or socket, lseek sets errno to ESPIPE and returns 1.
The file's offset can be greater than the file's current size, in which case the next write to the file will extend the file. This is referred to as creating a hole in a file and is allowed. Any bytes in a file that have not been written are read back as 0.
File hole would consume less blocks but is the same in file size.
3.7.ReadFunction#include <unistd.h> ssize_t read(int filedes, void *buf, size_t nbytes);
Before a successful return, the offset is incremented by the number of bytes actually read.
3.8.WriteFunction # include <unistd. h>ssize_t write(int filedes, const void *buf, size_t nbytes);
3.10. File SharingThe kernel uses three data structures to represent an open file, process table ,file table and v-node structure( Linux has no v-node. Instead, a generic i-node structure is used. Although the implementations differ, the v-node is conceptually the same as a generic i-node. Both point to an i-node structure specific to the file system.).
When two process share the same file, only the I-node table is the same. however, it is possible for more than one file descriptor entry to point to the same file table entry. (DUP fork)
TheLseekFunction modifies only the current file offset in the file table entry. No I/O takes place.
3.11. Atomic operationsappending to a fileThe UNIX system provides an atomic way to do this operation if we setO_appendFlag when a file is opened. As we described in the previous section, this causes the kernel to position the file to its current end of file before eachWrite. We no longer have to callLseekBefore eachWrite.
Note: After the o_append flag is used, any write operation can only be at the end, but the lseek can move and read at will.
Creating a filewe also said that check for the existence of the file and the creation of the file was stored med as an atomic operation (O_creatAndO_exclOptions forOpenFunction) 3.12.DUPAndDup2Functions#include <unistd.h> int dup(int filedes); int dup2(int filedes, int filedes2);
In dup2, if filedes2 is already open, it is first closed. If filedes equals filedes2, then dup2 returns filedes2 without closing it.
The new file descriptor that is returned as the value of the functions shares the same file table entry as the filedes argument.
As we describe in the next section, the close-on-exec file descriptor flag for the new descriptor is always cleared byDUPFunctions.
dup(filedes); is equivalent to fcntl(filedes, F_DUPFD, 0);
Similarly, the call
Dup2 (filedes, filedes2); is equivalent to (notconsidering atomic) Close (filedes2); fcntl (filedes, f_dupfd, filedes2 );
3.13.Sync,Fsync, AndFdatasyncFunctions
Traditional implementations of the UNIX system have a buffer cache or page cache in the kernel through which most disk I/O passes. when we write data to a file, the data is normally copied by the kernel into one of its buffers and queued for writing to disk at some later time. this is called delayed write.
#include <unistd.h> int fsync(int filedes); int fdatasync(int filedes);
void sync(void);
The sync function simply queues all the modified block buffers for writing and returns; it does not wait for the disk writes to take place.
The function sync is normally called periodically (usually every 30 seconds) from a system daemon, often called update. This guarantees regular flushing of the kernel's block buffers. The command sync(1) also calls the sync function.
The function fsync refers only to a single file, specified by the file descriptor filedes, and waits for the disk writes to complete before returning. The intended use of fsync is for an application, such as a database, that needs to be sure that the modified blocks have been written to the disk
WithFsync, The file's attributes are also updated synchronously. The aim of fdatasync () is to reduce disk activity for applications that do not require all metadata to be synchronized with the disk.
3.14.FcntlFunctionthe
FcntlFunction can change the properties of a file that is already open.# Include <fcntl. h>
Int fcntl (int
Filedes, int cmd,.../* int
Arg */);
TheFcntlFunction is used for five different purposes.
Duplicate an existing Descriptor (cmd =
F_dupfd)
GET/set file descriptor flags (cmd =F_getfdOr
F_setfd) GET/set file Status flags (cmd =F_getflOr
F_setfl)
GET/set asynchronous I/O ownership (cmd =F_getownOr
F_setown) GET/set record locks (cmd =F_getlk,
F_setlk, OrF_setlkw)
F_dupfd
The new descriptor shares the same file table entry
Filedes. (Refer
Figure 3.8.) But the new descriptor has its own set offile descriptor flags, and its
Fd_cloexecFile descriptor flag is cleared.
F_getfd
Return the file descriptor flags
Filedes as the value of the function. Currently, only one file descriptor flag is defined:
Fd_cloexecFlag.
F_setfd
Set the file descriptor flags for filedes. (fd_cloxec or 1)
F_getfl
Return the file Status flags for filedes as the value of the function.
Therefore, we must first useO_accmodeMask to obtain the access-mode bits and then compare the result against any of the three values.
F_setfl
Set the file Status flags to the value of the third argument (taken as an integer). The only flags that can be changed are
O_append,O_nonblock,O_sync,O_dsync,O_rsync,
O_fsync, AndO_async.
F_getown
Get the process ID or process group ID currently refreshing
SigioAndSigurgSignals. We describe these asynchronous I/O signals in
Section 14.6.2.
F_setown
Set the process ID or process group ID to receiveSigioAnd
SigurgSignals. A positive Arg specifies a process ID. A negative
Arg implies a process group ID equal to the absolute value
Arg.
CMD 2> file redirects stderr to the file (append );
5 <> temp. fooOpens the fileTemp. fooFor reading and writing on file descriptor 5.
val |= flags; /* turn on flags */
val &= ~flags; /* turn flags off */
Different file systems process o_sync differently. Linux ext2 does not process o_sync or Mac OS.
3.15. ioctl Function#include <unistd.h> /* System V */ #include <sys/ioctl.h> /* BSD and Linux */ #include <stropts.h> /* XSI STREAMS */ int ioctl(int filedes, int request, ...);