Linux程序设计:dup和dup2函数

目录

引例

实现cat命令

dup和dup2函数

文件重定向案例


  • 引例

  • 输入重定向
cat < mypasswd
  • 输出重定向
cat > mytxt
  • 追加输出重定向
cat >> mytxt

实现cat命令

  • 在src/cat.c
#include "io.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char * argv[1)
{
	int fd_in= STDIN_FILENO; //0
	int fd_out = STDOUT_FILENO; //1
	int i; 
	for(i = 1; i< argc; i++){
	    fd_in = open(argv[i], O_RDONLY); 
	    if(fd_in <0){
	    perror("open error"); 
	    continue;
	    }
	    copy(fd_in, fd_out); 
	    close(fd_in);
	}
	if(argc == 1) copy (fd_in, fd_out);
	
}


dup和dup2函数

#include <unistd.h>
int dup(int oldfd);
int dup2(int oldfd, int newfd);
  • 返回: 成功返回新文件描述符,出错返回-1
  • 功能: 文件描述符的复制
  • 参数
    • oldfd:原先的文件描述符
    • newfd:新的文件描述符
      • 把oldfd文件表项的指针复制给newfd
      • 就是把oldfd的指向复制一份到newfd(原来newid指向的文件被关闭),如此一来,再向newfd写输入就如同向oldfd写输入一样了。
  • 由dup返回的新文件描述符一定是当前可用文件描述符中的最小数值。
  • 用dup2则可以用newfd参数指定新描述符的数值。
    • 如果newfd已经打开,则先将其关闭。
    • 如若oldfd等于newfd,则dup2返回newfd,而不关闭它
  • 在进程间通信时可用来改变进程的标准输入和标准输出设备

文件重定向案例

#include "io.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
/*
*bin/mcat + iotek.txt(+为输入重定向)
*bin/mcat - iotek.txt(-为输出重定向)
*/
int main(int argc, char * argv[1)
{
	int fd_in, fd_out;
    int flag  = 0;
	int i;    
	for(i = 1; i < argc;i++){
	    if(!strcmp("+", argv[il)){
	        fd_in = open(argv[++il, O_RDONLY);
	            if(fd_in <0){
	            perror("open error");
	            exit(1);
            }
	//将标准输入重定向到文件
	if(dup2(fd_in, STDIN_FILENO)!= STDIN_FILENO){
		perror("dup2 error"); 
		exit(1);
		}
		close(fd_in);
	}else if(!strcmp("-", argv[i])){
		fd_out = open (argv[++i],O_WRONLY | O_CREAT | O_TRUNC, 0777); 
		if (fd_out < 0){
		    perror("open error"); 
		    exit(1);
	    //将标准输出重定向到文件
	        if(dup2(fd_out, STDOUT_FILENO)!= STDOUT_FILENO){
	            perror("dup2 error");
	            exit(1);
	        }
	    close(fd_out);	
	}else{
	    flag = 1; 
	    fd_in = open(argv[i], O_RDONLY);
	    if (fd in < 0){
		    perror ("open error"); exit(1);
	    }
	    if(dup2(fd_in, STDIN_FILENO)!= STDIN_FILENO){
	    	perror("dup2 error"); 
		    exit(1);
	    }
	    copy(STDIN_FILENO, STDOUT_FILENO);
	    close(fd_in);
	}
    if(!flag)
        copy(STDIN_FILENO, STDOUT_FILENO);
    return 0;	
}


  • 图示

  • 输入重定向示意图

  • 输出重定向示意图

  • 文件描述符复制案例(重定向)部分代码

int i = 1;
for(; i < argc; i++){
	if(!strcmp(argv[i], "+")){
			if(fd = open(argv[++i], O_RDONLY)<0){
                sys_err("open");
				}else{
				if(dup2(fd, STDIN_FILENO) != STDIN_FILENO){
						sys_err("dup2");
				} 
				close(fd);
			}
	}else if(!strcmp(argv[i], "-")){
			int fd = open(argv[++i],O_WRONLY|O_CREAT|O_TRUNC, 0777);
			if(fd < 0){sys_err("open");
				}else{
					if(dup2(fd, STDOUT_FILENO) != STDOUT_FILENO){
						sys_err("open");
						}
				close(fd);
			}	
	}else{fprintf(stderr, "usage: %s [+] file1 [-] file2\n", argv[0]);
			exit(1); 
		}
	}
copy(STDIN_FILENO, STDOUT_FILENO);
return 0;
}

猜你喜欢

转载自blog.csdn.net/baidu_41388533/article/details/108407104