复制文件描述符dup和dup2

文件描述符的复制:

dup和dup2是两个非常有用的系统调用,都是用来复制一个文件的描述符,使新的文件描述符也标识旧的文件描述符所标识的文件。

>> int dup(int oldfd);

>> int dup2(int oldfd,int newfd);

dup和dup2经常用来重定向进程的stdin,stdout和strerr。如:ls > log.txt 将ls的输出信息重定向到log.txt

1、dup函数

#include

int dup(int oldfd);

功能:复制oldfd文件描述符,并分配一个新的文件描述符,新的文件描述符是调用进程文件描述符表中最小可用的文件描述符。

参数:要复制的文件描述符oldfd。

返回值:成功返回新的文件描述符,失败返回-1;错误代码存于errno中。

#include 
#include 
#include 
#include 
#include 
#include 

int main(int argc,char *argv[])
{
        int fd,fd1;
        fd = open("test.txt",O_CREAT|O_WRONLY,0666);//S_IRWXU
        if(fd < 0)
        {
                perror("open:");
                _exit(-1);
        }
        close(1);
        fd1 = dup(fd);
        printf("fd1 = %d\n",fd1);
        return 0;
}

运行结果如下:

复制文件描述符dup和dup2_第1张图片

2、dup2:dup的升级版本

#include

int dup2(int oldfd, int newfd);

功能:复制一份打开的文件描述符oldfd,并分配新的文件描述符newfd,newfd也标识oldfd所标识的文件。

注意:newfd是小于文件描述符最大允许值的非负整数(<=1023,总共1024个文件描述符),如果newfd是一个已经打开的文件描述符,则首先关闭该文件,然后再复制。

参数:要复制的文件描述符oldfd,分配新的文件描述符newfd。

返回值:成功返回newfd;失败返回-1,错误代码存于errno中。

#include 
#include 
#include 
#include 
#include 
#include 

int main(int argc,char *argv[])
{
        int fd,fd1;
        fd = open("test.txt",O_CREAT|O_WRONLY,0666);
        if(fd < 0)
        {
                perror("open:");
                _exit(-1);
        }
        fd1 = dup2(fd,1);//让1也代表fd所代表的文件
        printf("fd1 = %d\n",fd1);
        return 0;
}

执行结果如下:

复制文件描述符dup和dup2_第2张图片

3、复制文件描述符后新旧文件描述符的特点

使用dup或dup2复制文件描述符后,新文件描述符和旧文件描述符指向(标识/代表)同一个文件,共享文件的锁定、读写位置和各项权限(只读/只写)。(属性)

当关闭新的文件描述符时,通过旧文件描述符仍可操作文件。

当关闭旧的文件描述符时,通过新的文件描述符仍可操作文件。

4、exec前后文件描述符的特点(进程没有变,即exec之后还能不能用exec前的那张文件描述符的表)

close_on_exec标志决定了文件描述符在执行exec后文件描述符是否可用。

文件描述符的close_on_exec标志默认是关闭的,即文件描述符在执行exec后文件描述符是可用的。

若没有设置close_on_exec标志位,进程中打开的文件描述符,及其相关的设置在exec后不变,可供新启动的程序使用。

设置close_on_exec标志位的方法:

int flags;

flags = fcntl(fd,F_GETFD); //获得标志

flags |= FD_CLOEXEC; //打开标志位

flags &= ~FD_CLOEXEC; //关闭标志位

fcntl(fd,F_SETFD,flags); //设置标志

#include 
#include 
#include 
#include 
#include 
#include 

int main(int argc,char *argv[])
{
        int fd_pipe[2];
        pid_t pid;
        if(pipe(fd_pipe)<0){
                perror("pipe");
        }
        pid = fork();
        if(pid < 0){
                perror("fork");
                _exit(-1);
        }
        else if(pid == 0){
                dup2(fd_pipe[1],1);
                execlp("expr","expr","6","+","8",NULL);
        }
        else{
                wait(NULL);
                char value[20] = "\0";
                read(fd_pipe[0],value,sizeof(value));
                printf("value = %s\n",value);
        }
        return 0;
}

编译执行后结果如下:


你可能感兴趣的:(Linux系统编程)