Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2416499
  • 博文数量: 298
  • 博客积分: 7876
  • 博客等级: 准将
  • 技术积分: 5500
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-23 13:39
文章存档

2013年(2)

2012年(142)

2011年(154)

分类: C/C++

2011-04-05 01:58:57

dupdup2也是两个非常有用的调用,它们的作用都是用来复制一个文件的描述符

例如:常用的三个描述符:

#include

STDIN_FILENO  = 0 标准输入

STDOUT_FILENO  = 1 标准输出

STDERR_FILENO = 2 标准错误输出

dup函数
它们经常用来重定向进程的stdinstdoutstderr
这两个函数的 原形如下:
#include
int dup( int oldfd );
int dup2( int oldfd, int targetfd )

利用函数dup,我们可以复制一个描述符。传给该函数一个既有的描述符,它就会返回一个新的描述符,注意新的描述符是当前能用的最小的。
这个新的描述符是传给它的描述符的拷贝。这意味着,这两个描述符共享同一个数据结构(问题:如果关闭其中一个描述符,另外一个也不能用了吗??)

例如,如果我们对一个文件描述符执行lseek操作,得到的第一个文件的位置和第二个是一样的。
下面是用来说明dup函数使用方法的代码片段:

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


需要注意的是,我们可以在调用fork之前建立一个描述符,这与调用dup建立描述符的效果是一样的,
子进程也同样会收到一个复制出来的描述符。
dup2函数
dup2
函数跟dup函数相似,但dup2函数允许调用者规定一个有效描述符和目标描述符的iddup2函数成功返回时,
目标描述符(dup2函数的第二个参数)将变成源描述符(dup2函数的第一个参数)的复制品,换句话说,
两个文件描述符现在都指向同一个文件,并且是函数第一个参数指向的文件。下面我们用一段代码加以说明:  
int oldfd;
oldfd = open("app_log", (O_RDWR | O_CREATE), 0644 );
dup2( oldfd, 1 );
close( oldfd );

本例中,我们打开了一个新文件,称为“app_log”,并收到一个文件描述符,该描述符叫做fd1。我们调用dup2函数,参数为oldfd1,这会导致用我们新打开的文件描述符替换掉由1代表的文件描述符(即stdout,因为标准输出文件的id1)。
任何写到stdout的东西,现在都将改为写入名为“app_log”的文件中

需要注意的是,dup2函数在复制了oldfd之后,会立即将其关闭,但不会关掉新近打开的文件描述符,因为文件描述符1现在也指向它
#include

#include

#include

#include

#include

                                                                                      

#define MAXNAME 256

#define BUFFSIZE 1024

int

main(int argc, char **argv)

{

        char     pathname[MAXNAME];

        int      fd;

        char     buf[BUFFSIZE];

        ssize_t  size_n;

        if(argc != 2)

        {

                printf("eg should: ./a.out pathname");

                exit(-1);

        }

//      gets(pathname);/*不推荐使用,因为没指定缓冲区大小,容易溢出*/

        strcpy(pathname, argv[1]);

     printf("file name : %s\n", pathname);

        if((fd = open(pathname, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR)) == -1)

        {

                printf("creat error");

        }

        else

        {

                printf("1\n");
                write(dup(1),"2\n", 2);
                write(dup(1),"3\n", 2);
                write(dup2(1, fd),"4\n", 2);
                write(fd, "5\n", 2);
                write(1, "6\n", 2);

                close(fd);

        }

        return 0;

}

 

程序结果:

标准输出:

1

2

3

4

5

6

文件里面没有内容,这说明dup2(1, fd)将1复制到了fd,现在fd和1都是标准输出。


#include

#include

#include

#include

#include

                                                                                      

#define MAXNAME 256

#define BUFFSIZE 1024

int

main(int argc, char **argv)

{

        char     pathname[MAXNAME];

        int      fd;

        char     buf[BUFFSIZE];

        ssize_t  size_n;

        if(argc != 2)

        {

                printf("eg should: ./a.out pathname");

                exit(-1);

        }

//      gets(pathname);/*不推荐使用,因为没指定缓冲区大小,容易溢出*/

        strcpy(pathname, argv[1]);

     printf("file name : %s\n", pathname);

        if((fd = open(pathname, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR)) == -1)

        {

                printf("creat error");

        }

        else

        {

                printf("1\n");
                write(dup(1),"2\n", 2);
                write(dup(1),"3\n", 2);
                write(dup2(fd, 1),"4\n", 2);
                write(fd, "5\n", 2);

                close(fd);
                write(1, "6\n", 2);

                close(fd);

        }

        return 0;

}

 

程序结果:

标准输出:

1

2

3

文件:

4

5

6

文件里面有内容,这说明dup2(fd, 1)将fd复制到了1,现在fd和1都是指向文件的描述符,并且关闭了fd依旧能正常工作。

阅读(1290) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~