@perkyoung
2015-01-08T17:04:56.000000Z
字数 2590
阅读 1612
UNIX
int open(const char* filename, int oflag, .../* mode_t mode */)
fd1 = open(filename, oflags);
fd2 = dup(fd1);
fd3 = open(filename, oflags);
前两行表明fd1,fd2同时指向了同一个文件表项,并且每调用一次open函数都会创建一个新的文件表项,fd则指向了另外一个文件表项,但是这两个文件表项指向同一个v节点
./a.out > outfile 2>&1 与./a.out 2>&1 > outfile的区别
shell是从左向右执行的,第一个首先将标准输出重定向到outfile文件,即文件描述符1代表outfile的文件表项,紧接着2>&1,相当于调用了dup2(1,2)函数,复制了一个文件描述符2,和1同时指向一个文件表项,通过前面可以知晓1指向的是outfile的文件表项,所以最终文件描述符1,2都指向了outfile文件表项。
第二个,首先调用dup(1,2),复制了一个文件描述符2,和1同时指向标准输出的文件表项,紧接着标准输出重定向到outfile文件中,这时候1描述符就指向了outfile文件表项,2依然指向的是标准输出的文件表项
off_t lseek(int fd, off_t offset, int whence);
int main() {
int fd = open("./tmp", O_RDWR | O_CREAT | O_APPEND);
int fd2 = dup(fd);
write(fd, "hello", 5);
int offset = lseek(fd, 0, SEEK_CUR);
char buf[10] = {0};
int offset_2 = lseek(fd2, 0, SEEK_CUR);
read(fd2, buf, 3);
printf("%c\n", buf[0]);
int n = lseek(fd2, -8, SEEK_CUR);
read(fd2, buf, 5);
printf("%s\n", buf);
write(fd, "end!", 4);
return 0;
}
程序中fd,fd2拥有的是同一个文件表项,也就是拥有同一个文件指针,对fd进行写操作会改变文件指针的位置,fd2读数据的时候,用的就是这个更改后的位置:write(fd, "hello", 5);
文件指针指向5,read(fd2, buf, 3);
会在当前的文件指针5的位置开始读,显然是没有数据的,这时候调用lseek(fd2, -8, SEEK_CUR);
,改变了指针位置,read(fd2, buf, 5);
,这时候就有数据,下面紧接着write(fd, "end!", 4);
,本来是可以在上次读到的位置继续写的,但是O_APPEND
这个标志起到了作用,每当write的时候会先将文件标志移动到最后,再写。
ssize_t read(int fd, void *buf, size_t count);
dup,fork新增的文件描述符和原来的文件描述符指向同一个文件表项,
一个文件被多个进程打开,或者被一个进程打开多次,他们是如何协同工作的呢?下面3中数据结果决定了这个性质
int dup(int oldfd);
int dup2(int oldfd, int newfd);
int fcntl(int fd, int cmd, ... /* arg */ );
#define O_ACCMODE 0003
#define O_RDONLY 00
#define O_WRONLY 01
#define O_RDWR 02
判断一个文件的这三个属性,需要用& O_ACCMODE,获得这个标志位