Chapter 4
This commit is contained in:
@@ -1,42 +1,45 @@
|
|||||||
# Chapter 4 – Advanced File I/O
|
# Chapter 4 – Advanced File I/O
|
||||||
|
|
||||||
## File Metadata and the `stat` Family
|
## Scatter/Gather I/O
|
||||||
- Use `stat()`, `fstat()`, `lstat()` to retrieve file metadata:
|
- Scatter/gather I/O allows reading or writing data to/from multiple buffers in a single system call.
|
||||||
- File type, size, inode number, permissions, ownership, timestamps (atime, mtime, ctime).
|
- Uses `readv()` and `writev()`:
|
||||||
- The `stat` structure includes all these details.
|
- `readv(fd, iov, iovcnt)`: reads into multiple buffers (`iov` array).
|
||||||
|
- `writev(fd, iov, iovcnt)`: writes from multiple buffers.
|
||||||
|
- Improves efficiency by reducing system calls.
|
||||||
|
|
||||||
## File Types
|
## Event Poll (`select()`, `poll()`, `epoll`)
|
||||||
- Regular file, directory, symbolic link, character/block device, FIFO, socket.
|
- Traditional multiplexing: `select()`, `poll()` (limited scalability).
|
||||||
- Use macros like `S_ISREG()`, `S_ISDIR()` to test file types.
|
- Linux-specific: `epoll` for efficient event notification.
|
||||||
|
- `epoll_create()`: create epoll instance.
|
||||||
|
- `epoll_ctl()`: control interest list (add, modify, remove fds).
|
||||||
|
- `epoll_wait()`: wait for events.
|
||||||
|
- Edge-triggered vs level-triggered modes.
|
||||||
|
|
||||||
## File Permissions and Modes
|
## Memory-Mapped Files (`mmap()`)
|
||||||
- Represented by 12 bits (e.g., `rwxr-xr--`), plus sticky/SUID/SGID bits.
|
- Maps files or devices into memory for direct access.
|
||||||
- Manipulate with `chmod()`, `fchmod()`, `umask()`.
|
- System calls: `mmap()`, `munmap()`.
|
||||||
- Ownership changed with `chown()` and `fchown()`.
|
- Benefits: faster I/O, shared memory.
|
||||||
|
- Use `msync()` to synchronize changes.
|
||||||
|
- Resizing mappings, changing protections.
|
||||||
|
- Advisory calls:
|
||||||
|
- `posix_fadvise()`: give advice about expected I/O patterns.
|
||||||
|
- `readahead()`: prefetch file data.
|
||||||
|
- Pros and cons of memory mapping.
|
||||||
|
|
||||||
## Links
|
## Asynchronous I/O and I/O Scheduling
|
||||||
- **Hard links**: multiple filenames point to the same inode.
|
- Distinction between synchronous and asynchronous I/O.
|
||||||
- **Symbolic links**: separate files that reference other paths; can be broken.
|
- Linux AIO APIs for asynchronous operations.
|
||||||
- Use `link()`, `unlink()`, `symlink()`, `readlink()`.
|
- I/O schedulers:
|
||||||
|
- Manage disk request ordering.
|
||||||
|
- Examples: CFQ, noop, deadline.
|
||||||
|
- Optimizing I/O performance by choosing schedulers.
|
||||||
|
- Concepts of disk addressing and request life cycle.
|
||||||
|
|
||||||
## Directories
|
## Miscellaneous
|
||||||
- Open with `opendir()`, read entries with `readdir()`.
|
- `ioctl()`: device-specific operations.
|
||||||
- Low-level: `getdents()` system call.
|
- Zero-copy transfers: `sendfile()`, `splice()`.
|
||||||
|
|
||||||
## File Timestamps
|
---
|
||||||
- `utime()`, `utimes()`, `futimens()`, and `utimensat()` to update access/modification times.
|
|
||||||
|
|
||||||
## File Descriptors and Flags
|
> This chapter covers advanced Linux I/O techniques aimed at improving performance and flexibility in system programming.
|
||||||
- Manipulate with `fcntl()`:
|
|
||||||
- Set non-blocking mode (`O_NONBLOCK`), FD_CLOEXEC flag, file locks.
|
|
||||||
- Duplicate with `dup()` and `dup2()`.
|
|
||||||
|
|
||||||
## File Locking
|
|
||||||
- `flock()` for advisory locking (whole file).
|
|
||||||
- `fcntl()` for POSIX record locking (ranges).
|
|
||||||
|
|
||||||
## Temporary Files
|
|
||||||
- `tmpfile()`, `mkstemp()` are safe methods to create temp files.
|
|
||||||
|
|
||||||
## Summary
|
|
||||||
- Chapter 3 focuses on extended file handling: metadata, links, directories, file modes, and advanced descriptor manipulation.
|
|
||||||
|
|||||||
BIN
chp4/buccaneer.txt
Executable file
BIN
chp4/buccaneer.txt
Executable file
Binary file not shown.
41
chp4/readv.c
Normal file
41
chp4/readv.c
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
char foo[48], bar[51], baz[49];
|
||||||
|
int fd = open("buccaneer.txt", O_RDONLY);
|
||||||
|
if (fd == -1) {
|
||||||
|
perror("open");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup our iovec structures
|
||||||
|
struct iovec iov[3];
|
||||||
|
iov[0].iov_base = foo;
|
||||||
|
iov[0].iov_len = sizeof(foo);
|
||||||
|
iov[1].iov_base = bar;
|
||||||
|
iov[1].iov_len = sizeof(bar);
|
||||||
|
iov[2].iov_base = baz;
|
||||||
|
iov[2].iov_len = sizeof(baz);
|
||||||
|
|
||||||
|
// read into the structures with a single call
|
||||||
|
int nr = readv(fd, iov, 3);
|
||||||
|
if (nr == -1) {
|
||||||
|
perror("readv");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
printf("%d: %s", i, (char *)iov[i].iov_base);
|
||||||
|
|
||||||
|
if (close(fd)) {
|
||||||
|
perror("close");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
45
chp4/writev.c
Normal file
45
chp4/writev.c
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
struct iovec iov[3];
|
||||||
|
|
||||||
|
char *buf[] = {
|
||||||
|
"The term buccaneer comes from the word boucan.\n",
|
||||||
|
"A boucan is a wooden frame used for cooking meet.\n",
|
||||||
|
"Buccaneer is the West Indies name for a pirate.\n"
|
||||||
|
};
|
||||||
|
|
||||||
|
int fd = open("buccaneer.txt", O_WRONLY | O_CREAT | O_TRUNC);
|
||||||
|
if (fd == -1) {
|
||||||
|
perror("open");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fill out three iovec structures
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
iov[i].iov_base = buf[i];
|
||||||
|
iov[i].iov_len = strlen(buf[i]) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// with a single call, write them all out
|
||||||
|
ssize_t nr = writev(fd, iov, 3);
|
||||||
|
if (nr == -1) {
|
||||||
|
perror("writev");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("wrote %lu bytes\n", nr);
|
||||||
|
|
||||||
|
if (close(fd)) {
|
||||||
|
perror("close");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user