标准流描述符:
/* Standard file descriptors. */ #define STDIN_FILENO 0 /* Standard input. */ #define STDOUT_FILENO 1 /* Standard output. */ #define STDERR_FILENO 2 /* Standard error output. */
打开、创建、关闭文件:
#define O_ACCMODE 0003 /* O_ACCMODE = O_RDONLY | O_WRONLY | O_RDWR */ #define O_RDONLY 00 #define O_WRONLY 01 #define O_RDWR 02 #define O_CREAT 0100 /* open() 第 3 个参数指定权限位 */ #define O_EXCL 0200 #define O_NOCTTY 0400 #define O_TRUNC 01000 #define O_APPEND 02000 #define O_NONBLOCK 04000 /* 非阻塞 */ #define O_SYNC 04010000 #define O_FSYNC O_SYNC #define O_ASYNC 020000 #define O_DIRECTORY __O_DIRECTORY /* 打开非目录出错 */ #define O_NOFOLLOW __O_NOFOLLOW /* 打开符号链接出错 */ #define O_CLOEXEC __O_CLOEXEC /* exec() 时关闭 */ int open (const char *__file, int __oflag, ...); int openat (int __fd, const char *__file, int __oflag, ...);// open(__file, O_WRONLY | O_CREAT | O_TRUNC, __mode) int creat (const char *__file, mode_t __mode); int close (int __fd);
移动指针:
#define SEEK_SET 0 /* Seek from beginning of file. */ #define SEEK_CUR 1 /* Seek from current position. */ #define SEEK_END 2 /* Seek from end of file. */ __off_t lseek (int __fd, __off_t __offset, int __whence); __off64_t lseek64 (int __fd, __off64_t __offset, int __whence);
读写(注意原子操作):
ssize_t read (int __fd, void *__buf, size_t __nbytes); ssize_t pread (int __fd, void *__buf, size_t __nbytes, __off_t __offset); ssize_t write (int __fd, const void *__buf, size_t __n); ssize_t pwrite (int __fd, const void *__buf, size_t __n, __off_t __offset);
文件共享:
int dup (int __fd); int dup2 (int __fd, int __fd2); // 先关闭 fd2, 再复制 fd -> fd2
刷新内部缓冲:
void sync (void); // 只写入队列,不等待磁盘 I/O int fsync (int __fd); // 等待磁盘 I/O,更新数据和属性 int fdatasync (int __fildes); // 等待磁盘 I/O,只更新数据
fcntl()和ioctl():
#define F_DUPFD 0 /* Duplicate file descriptor. */ #define F_DUPFD_CLOEXEC 1030 /* Duplicate file descriptor with close-on-exit set. */ #define F_GETFD 1 /* Get file descriptor flags. */ #define F_SETFD 2 /* Set file descriptor flags. */ #define F_GETFL 3 /* Get file status flags. */ #define F_SETFL 4 /* Set file status flags. */ #define F_SETOWN __F_SETOWN /* Get owner (process receiving SIGIO). */ #define F_GETOWN __F_GETOWN /* Set owner (process receiving SIGIO). */ int fcntl (int __fd, int __cmd, ...); int ioctl (int __fd, unsigned long int __request, ...);
/dev/fd:
每个进程看到的都不一样,例如:
# ls -l /dev/fd/ > a.txt # cat a.txt total 0 lrwx------. 1 root root 64 May 20 16:34 0 -> /dev/pts/0 l-wx------. 1 root root 64 May 20 16:34 1 -> /root/a.txt lrwx------. 1 root root 64 May 20 16:34 2 -> /dev/pts/0 lr-x------. 1 root root 64 May 20 16:34 3 -> /proc/6259/fd
习题3.2 自己实现一个dup2():
int mydup2 (int fd, int fd2) { int fd_close[20] = { 0 }; int fd_temp; if(fd == fd2) { return fd2; } close(fd2); while((fd_temp = dup(fd)) != fd2) { fd_close[fd_temp] = 1; } for(int i = 0; i < (sizeof fd_close / sizeof fd_close[0]); i ++) { if(fd_close[i]) { close(i); } } return fd2; }
习题3.3 考虑下边代码,显然 fd1 和 fd2 指向同一个 vnode:
#include <stdio.h> #include <fcntl.h> #include <unistd.h> int main(void) { int fd11 = open("a.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644); int fd12 = dup(fd11); int fd21 = open("a.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644); // abcdefg write(fd11, "abcdefg", 7); lseek(fd11, 0, SEEK_SET); // xxxxxxx write(fd12, "xxxxxxx", 7); // xxxxxxxyyyyyyy lseek(fd21, 0, SEEK_END); write(fd21, "yyyyyyy", 7); // xxxxxxxaaaaaaa write(fd11, "aaaaaaa", 7); return 0; }
习题3.6 以下代码说明可以任意位置读,写入总在尾部追加:
#include <stdio.h> #include <fcntl.h> #include <unistd.h> int main(void) { char buffer[4] = { 0 }; int fd = open("a.txt", O_RDWR | O_CREAT | O_TRUNC | O_APPEND, 0644); write(fd, "abcdefg", 7); lseek(fd, 2, SEEK_SET); printf("%d\n", read(fd, buffer, 3)); printf("%s\n", buffer); printf("%d\n", write(fd, "xxx", 3)); return 0; }
时间: 2024-10-16 06:30:30