本文共 3809 字,大约阅读时间需要 12 分钟。
dup() 和 dup2() 都可以用来复制一个现有的文件描述符,这两个函数声明如下:
#includedup() 函数返回的新文件描述符一定是当前可用文件描述符中的最小值。int dup(int oldfd);int dup2(int oldfd, int newfd);
测试代码:
#include#include #include #include #include #include #include print_line(int n) { char buf[32]; const char *ptr = "hello"; snprintf(buf, sizeof(buf), "Line #%d\n", n); write(1, buf, strlen(buf)); } int main() { int fd; print_line(1); print_line(2); print_line(3); /*重定向标准输出 stdout 到文件 dup.out 中*/ fd = open("dup.out", O_WRONLY|O_CREAT,0666); assert(fd>=0); printf("fd=%d\n", fd); dup2(fd, 1); print_line(4); print_line(5); print_line(6); close(fd); close(1); return 0; }
程序运行以及输出结果:
beyes@linux-beyes:~/C/call> ./dup.exe Line #1 Line #2 Line #3 fd=3 beyes@linux-beyes:~/C/call> cat dup.out Line #4 Line #5 Line #6
27行:经过 dup2() 函数后,标准输出就成为了 fd 的一个副本,也就是说,操作标准输出描述符 1 也就相当于操作到了 fd 上( 新旧文件描述符指向同一个文件,共享所有的锁定、读写指针和各项权限或标志位)。效果如像上面所示,标准输出被的重定向到文件中去了。
#include#include #include #include #include #include int main(int argc, char **argv, char **environ){ pid_t pid; int fd[2]; if (pipe(fd)) { printf("create pipe failed!\n"); exit(1); } pid = fork(); switch(pid) { case -1: printf("fork error!\n"); exit(1); case 0: close(fd[0]); close(1); dup(fd[1]); sleep(5); system("ls -l"); exit(0); default: close(fd[1]); char message[4096]; read(fd[0], message, 4096); printf("hello world\n"); printf("%", message); } return 0;}
在子进程中睡眠 5 秒和在父进程中故意输出 hello world ,这是为了测试管道读写的阻塞性质。由于建立了管道,在子进程里如果没有向标准输出内容(已经调用 dup() 后)或者子进程没有退出,那么父进程会被阻塞,直到能从管道里读到些什么东西为止。如果子进程并没有向管道里写东西,而是直接退出了,那么父进程检测到子进程已经退出,则管道不再阻塞,直接从自定义的缓冲区里读些东西(遇到‘\0‘为止)也就跟着退出了。beyes@linux-beyes:~/C/pipe> ./dup2.exe hello world 总计 84 -rw-r--r-- 1 beyes users 1446 07-23 17:38 dual_pipe.c -rwxr-xr-x 1 beyes users 12407 07-23 17:38 dual_pipe.exe -rw-r--r-- 1 beyes users 736 07-23 22:03 dup2.c -rwxr-xr-x 1 beyes users 11932 07-23 22:03 dup2.exe -rw-r--r-- 1 beyes users 769 07-22 01:40 pipe.c -rwxr-xr-x 1 beyes users 12266 07-22 01:41 pipe.exe -rw-r--r-- 1 beyes users 153 07-22 01:17 strlen.c -rwxr-xr-x 1 beyes users 11373 07-22 01:17 strlen.exe
转载地址:http://tvlli.baihongyu.com/