dup,dup2文件和描述符重定位

dup和dup2
#include <unistd.h>
int dup(int oldfd);
dup
  功能:复制某个已打开的文件描述符,得到一个新的文件描述符,这个新的描述符,也指向被复制描述符所指向的文件
    比如 4指向了文件a.txt ,从4复制出5,5也指向a.txt
  返回值:
    成功:返回复制后的新文件描述符
    失败:-1 并设置errno
  参数:
  oldfd:会被复制的已经存在的文件描述符

#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

int main(int argc,char *argv[]){
    int fd1=0;
    int fd2=0;
    fd1=open("./file.txt",O_RDWR);
    // fd2=dup(fd1);
    fd2=dup2(fd1,5);
    printf("fd1=%d,fd2=%d\n",fd1,fd2 );
    write(fd1,"hello\n",6);
    write(fd2,"world\n",6);
    return 0;
}

dup2
int dup2(int oldfd, int newfd);
功能:同dup,在dup2中可以指定新文件描述符
  如果这个新文件描述符已经被打开,dup2会先把它关闭,再使用
  如dup2(2,3)
  从2复制出3,让3也指向2所指向的文件,如果3之前被打开过,dup2会关闭它,然后再使用
dup2与dup区别
dup:自己到文件描述符池中找到新文件描述符
dup2:可以自己指定新文件描述符
返回值
  成功:返回复制后的新文件描述符
  失败:返回-1,设置errno
参数:
  oldfd:会被复制的已经存在的文件描述符
  newfd:新的文件描述符

文件描述符表
没加O_APPEND为何没有出现覆盖
使用dup,dup2复制文件方式实现文件共享时,不管复制出多少个文件描述符,他们永远只有一个文件表,
所以使用任何一个文件描述符去操作文件时,最后使用的都是通过同一个文件位移量,不管谁操作后文件位移量都会被更新
因此不会出现覆盖

06-dup,dup2和重定位_linux网络编程

 

dup,dup2实现重定位
某文件描述符原来指向了A文件,输出数据到A文件,但是重定位后,文件描述符指向了B文件,
  输出时数据输出到了B文件,就是改变文件描述符指向
  printf的实现是write(1)的调用把文件输出到显示屏幕上,现在把printf的数据写入到file.txt,显然无法改write的底层实现
  可以把1这个描述符重新定位到file.txt文件

步骤:
open file.txt 返回一个文件描述符,比如3
close(1)不要让1指向/dev/stdout
使用dup或者dup2把1复制到3 上,也让1指向file.txt

#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>

int main(int argc,char *argv[]){
    int fd1=0;
    int fd2=0;
    
    fd1=open("./file.txt",O_RDWR);
    // close(1);
    // dup(fd1);//或者 fd2=dup(fd1)   dup会找到描述符池中最小的那个 此处即为1 拿来复制返回给fd2即为1

    dup2(fd1,1);
    
    printf("fd1=%d,fd2=%d\n",fd1,fd2 );
    
    return 0;
}

对0重定位实现scanf从file.txt读取数据

#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>

int main(int argc,char *argv[]){
    int fd1=0;
    fd1=open("./file.txt",O_RDWR); //file.txt里是hello world
    dup2(fd1,STDIN_FILENO);
    char s[20] ={0};
    scanf("%[^\n]",&s);
    printf("s=%s\n", s);
    
    return 0;
}

重定位命令
ls>file.txt
ls会调用write(1 ,..)
使用>时会调用dup函数

文件共享操作
1.单进程多次open
2.多个进程多个open