dup和dup2以及cat函数函数

今日命令:

more filenamen   //分屏显示filename 内容
od -c   filename    //使用二进制形式查看文件内容

dup和dup2也是两个非常有用的调用,它们的作用都是用来复制一个文件的描述符。它们经常用来重定向进程的stdin、stdout和stderr。这两个函数的原形如下:

#include 
int dup( int oldfd );
int dup2( int oldfd, int targetfd );

利用函数dup,我们可以复制一个描述符。传给该函数一个既有的描述符,它就会返回一个新的描述符,这个新的描述符是传给它的描述符的拷贝。这意味着,这两个描述符共享同一个数据结构。例如,如果我们对一个文件描述符执行lseek操作,得到的第一个文件的位置和第二个是一样的。下面是用来说明dup函数使用方法的代码片段:

int fd1, fd2;
...
fd2 = dup( fd1 );

dup2函数跟dup函数相似,但dup2函数允许调用者规定一个有效描述符和目标描述符的id。在使用dup2的时候若第二个参数的描述符targetfd已经打开则现将其关闭, dup2函数成功返回时,目标描述符(dup2函数的第二个参数)将变成源描述符(dup2函数的第一个参数)的复制品,换句话说,两个文件描述符现在都指向同一个文件,并且是函数第一个参数指向的文件。下面我们用一段代码加以说明:
dup和dup2以及cat函数函数_第1张图片

 int oldfd;
 oldfd = open("app_log", (O_RDWR | O_CREATE), 0644 );
 dup2( oldfd, 1 );
 close( oldfd );
#include 
#include 
#include 

int main()
{
    int pfds[2];

    if ( pipe(pfds) == 0 ) {

    if ( fork() == 0 ) {

        close(1);
        dup2( pfds[1], 1 );
        close( pfds[0] );
        execlp( "ls", "ls", "-l", NULL );

    } else {

        close(0);
        dup2( pfds[0], 0 );
        close( pfds[1] );
        execlp( "wc", "wc", "-l", NULL );

    }

    return 0;
}

//复制文件描述符并向文件写数据

#include 
#include 
#include 
#include 
#include 

void main()
{
        int fd,newfd;
        char *bufFD="Advanced Programming! write by fd\n";
        char *bufNewFD="Advanced Programming! write by NewFD\n";
        fd = open("test.txt",O_RDWR|O_CREAT,0644);
        if(fd==-1)
        {
                printf("open file error%m\n");
                exit(-1);
        }

        //开始复制了
        newfd = dup(fd);
        //使用fd写
        write(fd,bufFD,strlen(bufFD));
        close(fd);

        //使用newfd写
        write(newfd,bufNewFD,strlen(bufNewFD));

        if(close(newfd)==-1)
        {
                printf("close error\n");
        }
        exit(0);
}

实现简单cat命令:实现的是无论输入多少参数都能将其转化为标准输出输出出来。

#include "io.h" 
#include 
#include 
#include 
#include 
#include 


int main(int argc, char * argv[])
{
    int fd_in = STDIN_FILENO;
    int fd_out = STDOUT_FILENO;

    int i;
    for(i = 1; i < argc; i ++)
    {   //写上fro循环是为了无论输入几个命令行参数,都能够将其转换为标准输出输出出来
        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);
    }

    return 0;
}

io.c文件

#include "io.h"
#include 
#include 
#include 
#include 
#include 
#include 

#define BUFFER_LEN 1024

void copy(int fdin, int fdout)
{
    char buffer[BUFFER_LEN];
    ssize_t size;
    while(( size = read(fdin, buffer, BUFFER_LEN )) > 0)
    {   
        printf("current %ld\n",lseek(fdin,0L,SEEK_CUR));
        if( write( fdout, buffer, size) != size)
        {
            fprintf(stderr,"write error: %s\n",strerror(errno));
            exit(1);
        }
    }
    if(size < 0)
    {
        fprintf(stderr, "read error: %s\n",strerror(errno));
        exit(1);
    }

}


io.h头文件

#ifndef __IO_H
#define __IO_H

extern void copy(int fdin, int fdout);

#endif

使用dup函数,打造升级版cat命令:

#include "io.h"
#include 
#include 
#include 
#include 
#include 

/*
*bin/mcat + iotec.txt (+为输入重定向)
*bin/mcat - iotec.txt(-为输出重定向)
*/



int main(int argc, char * argv[])
{
    int fd_in = STDIN_FILENO;
    int fd_out = STDOUT_FILENO;
    int flag = 0;

    int i;
    for(i = 1; i < argc; i ++)
    {   //写上fro循环是为了无论输入几个命令行参数,都能够将其转换为标准输出输出出来
        if(!strcmp("+", argv[i]))
        {
            fd_in = open(argv[++i],O_RDONLY);
            if(fd_in < 0)
            {
                perror("open error");
            }
            //将标准输入重定向到文件
            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 fd_out error!");
                exit(1);               
            }
            //将标准输出重定向到文件
            if(dup2(fd_out, STDOUT_FILENO) != STDOUT_FILENO)
            {
                perror("dup2 error");
                exit(1);
            }
        }
        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;
}




你可能感兴趣的:(linux,嵌入式-Linux)