调用open函数来打开一个已存在的文件或创建一个新文件。
int open(char *filename, int flags, mode_t mode);
open函数将filename转换为一个文件描述符,并返回描述符数字。返回地描述符是进程中当前没有打开的最小描述符(从3开始)。flags参数指明如何访问这个文件:
O_RDONLY:只读
O_WRONLY:只写
O_RDWR:可读可写
O_CREAT:如果文件不存在,创建一个空文件
O_TRUNC:若文件已经存在,截断它
O_APPEND:在每次写操作前,设置文件位置到文件的结尾处
#include "csapp.h"
int main()
{
int fd1, fd2;
fd1 = Open("foo.txt", O_RDONLY, 0);
Close(fd1);
fd2 = Open("foo.txt", O_RDONLY, 0);
printf("fd2 = %d\n", fd2);
exit(0);
}
输出结果为:fd2 = 3
分析:fd1=3(最小的数),关闭文件后这个描述符会恢复到可用的描述符池中,fd2=3。
#include "csapp.h"
int main(int argc, char *argv[])
{
int fd1, fd2, fd3;
char c1, c2, c3;
char *fname = argv[1];
fd1 = Open(fname, O_RDONLY, 0);
fd2 = Open(fname, O_RDONLY, 0);
fd3 = Open(fname, O_RDONLY, 0);
dup2(fd2, fd3);
Read(fd1, &c1, 1);
Read(fd2, &c2, 1);
Read(fd3, &c3, 1);
printf("c1 = %c, c2 = %c, c3 = %c\n", c1, c2, c3);
Close(fd1);
Close(fd2);
Close(fd3);
return 0;
}
输出结果为:c1 = a, c2 = a, c3 = b
fd1读取a, fd2光标还是停留在a之前,dup2函数将fd3重定位为fd2,fd3光标停留在ab之间,读取b。
#include "csapp.h"
int main(int argc, char *argv[])
{
int fd1;
int s = getpid() & 0x1;
char c1, c2;
char *fname = argv[1];
fd1 = Open(fname, O_RDONLY, 0);
Read(fd1, &c1, 1);
if (fork()) {
/* Parent */
sleep(s);
Read(fd1, &c2, 1);
printf("Parent: c1 = %c, c2 = %c\n", c1, c2);
} else {
/* Child */
sleep(1-s);
Read(fd1, &c2, 1);
printf("Child: c1 = %c, c2 = %c\n", c1, c2);
}
return 0;
}
运行结果:
Parent: c1 = a, c2 = b
Child: c1 = a, c2 = c
首先fd1读取a,光标停留在ab之间。然后fork函数创建进程,子进程休眠,fd1继续读取了b,输出Parent: c1 = a, c2 = b。父进程中,fd1光标此时停留在bc之间,因为刚刚子进程读取了b字符,所以现在读取c字符。