Chapter5 deep Dive into file I/O
This section describes another system call related to file operations: Multi-purpose Fcntl () and shows one of its applications reading and setting the status flags for open files.
5.1 Atomic operating and competitive conditions
All system calls are performed in an atomic operation. Is that the kernel guarantees that all the steps in a system call will be executed once as a standalone operation without interruption to other processes or threads.
To create a file exclusively:
Open () returns an error if the file to be opened already exists, when both O_EXCL and O_creat are set as the open () flag bit. Guaranteed that the process is the creator of the open file.
Append data to the tail of the file:
Multiple processes add data to the end of the same file at the same time.
5.2 File Control operation: Fcntl ()
The FCNTL () system call performs a series of control operations on an open file descriptor.
#include <fcntl.h>
int fcntl (int fd, int cmd, ...);
5.3 Status flags for open files
One of the uses of Fcntl () is to get or modify its access mode and status ID for an open file.
int flags, AccessMode;
Flags = FCNTL (FD, F_GETFL);
if (flags =-1)
Errexit ("Fcntl");
After the above code, you can test whether the file is open synchronously with the following code:
if (Flags & O_sync)
printf ("Wirtes is synchronize\n");
5.4 Relationship between file descriptors and open files
File descriptor for process level
System-Level Open File Table
I-node table for file systems
5.5 Copying file descriptors
The DUP () call copies an open file descriptor OLDFD and returns a new descriptor. They point to the same open file handle.
#include <unistd.h>
int dup (int oldfd);
5.6 I/o:pread () and Pwrite () at a file-specific offset
System Ayung Pread () and Pwrite () complete work similar to read and write () except that the first two do file IO operations at the location specified by the offset parameter, rather than the current offset of the file, and they will not modify the current offset of the file.
#include <unistd.h>
ssize_t pread (int fd, void *buf, size_t count, off_t offset);
ssize_t pwirte (int fd, const void *buf, size_t count, off_t offset);
The Pread () call is equivalent to the following call to incorporate the same atomic operation:
off_t orig;
Orig = Lseek (fd, 0,seek_cur);
Lseek (FD, offset, seek_set);
s = Read (FD, buf, Len);
Lseek (FD, origin, Seek_set);
5.7 Decentralized input and centralized output (Scatter-gather I/O): Readv () and Writev ()
#include <sys.uio.h>
ssize_t readv (int fd, const struct IOVEC *iov, int iovcnt);
ssize_t Wirtev (int fd, const struct IOVEC *iov, int iovcnt);
These system transfers do not simply read and write to a single buffer, but can transmit multiple buffers at one time. The array Iov defines a set of buffers that are used to transmit data. The integer iovcnt specifies the number of members of the IOV. Each member of the IOV is a data structure in the following form.
struct IOVEC
{
void *iov_base;
size_t Iov_len;
}
5.8 Truncate files: Truncate () and ftruncate () system calls
The truncate () and ftruncate () system calls set the file to the value specified by the length parameter.
#include <unistd.h>
int truncate (const char* pathname, off_t length);
int ftruncate (int fd, off_t length);
If the file is longer than the parameter length, the call discards the excess, and if it is less than the parameter length, the call adds a series of empty bytes or a file hole at the end of the file.
5.9 Non-blocking I/O
The open file is the specified O_nonblock flag, with the purpose of two:
(1): If the open () call fails to open the file immediately, an error is returned, not blocked.
(2): After the call to open () succeeds, subsequent I/O operations are also non-blocking.
Pipes, FIFO, sockets, and devices all support nonblocking mode.
5.10 Large File I/O
Bridging LFS API
To use the transitional LFS API, you must define the Largefile64_source function test macro when compiling the program. Fopen64 (), Open64 (), lseek64 (), Truncate64 (), Stat64 (), Mmap64 () and Setrlimit64 ().
Call Open64 (), which is equivalent to calling open () to specify the O_LARGEFILE flag.
5.11/DEV/FD Directory
For each process, the kernel provides a special virtual directory/dev/fd. This directory contains the file name "/dev/fd/n", where n is the number corresponding to the open file description typeface in the process. For example,/dev/fd/0 corresponds to the standard input for a process.
e.g.: equivalent, equivalent to copying the corresponding file descriptor.
FD = open ("/DEV/FD/1", o_wronly);
FD = DUP (1)
5.12 Creating temporary files
Mkstemp () and Tmpfile ()
Based on the template provided by the caller, the mkstemp () function generates a unique file name and opens the file, returning a filename descriptor that can be used for I/O calls.
#include <stdlib.h>
int mkstemp (char *template);
The template parameter takes the form of a path, where the most 6 characters must be xxxxxx.
int FD;
Char template[] = "/tmp/somestringxxxxxx";
FD = mkstemp (template);
if (fd = =-1)
Errexit ("Mkstemp");
unlink (template);
The Tmpfile () function creates a temporary file with a unique name and opens it in read-write mode.
#include <stdio.h>
FILE *tmpfile (void);
"Linux_unix system Programming" CHAPTER5 deep dive into file IO