1. 程式人生 > >Linux 系統呼叫 dup()和dup2()

Linux 系統呼叫 dup()和dup2()

1、dup()

dup()系統呼叫會建立檔案描述符的一個拷貝:

(1)新生成的檔案描述符是程序中最小的未使用的檔案描述符,0 、1 、2對應標準輸入、標準輸出、標準錯誤輸出

(2)如果拷貝成功,那麼原始的和拷貝的檔案描述符可能會交叉使用

(3)兩者都指向同一個開啟的檔案描述符,因此共享檔案偏移量和檔案狀態標誌

語法:

int dup(int oldfd);
oldfd: 舊的檔案描述符的拷貝被建立

例項如下:

#include<stdio.h> 
#include <unistd.h> 
#include <fcntl.h> 
  
int main() 
{ 
    // open() returns a file descriptor file_desc to a  
    // the file "dup.txt" here" 
  
    int file_desc = open("dup.txt", O_WRONLY | O_APPEND); 
      
    if(file_desc < 0) 
        printf("Error opening the file\n"); 
      
    // dup() will create the copy of file_desc as the copy_desc 
    // then both can be used interchangeably. 
  
    int copy_desc = dup(file_desc); 
          
    // write() will write the given string into the file 
    // referred by the file descriptors 
  
    write(copy_desc,"This will be output to the file named dup.txt\n", 46); 
          
    write(file_desc,"This will also be output to the file named dup.txt\n", 51); 
      
    return 0; 
}

2、dup2()

dup2()系統呼叫與dup類似,它們之間的基本不同在於dup2()不使用最小的未使用的檔案描述符編號,它使用指定的檔案描述符編號。

語法:

int dup2(int oldfd, int newfd);
oldfd: old file descriptor
newfd new file descriptor which is used by dup2() to create a copy.

關鍵點:

dup()和dup2()系統呼叫都要包含unistd.h標頭檔案

如果newfd描述符之間就打開了,那麼在重用之前會被關閉

如果oldfd是非法的檔案描述符,則系統呼叫失敗,newfd也不會關閉

如果oldfd是有效的檔案描述符,newfd的值和oldfd的值相同,那麼dup2()什麼都不做,直接返回newfd

 

使用dup2()系統呼叫的小技巧:

因為newfd可以是任何的檔案描述符,以下的例項使用了C的標準輸出stdout。這能實現把printf語句的輸出寫到oldfd關聯的檔案中:

#include<stdlib.h> 
#include<unistd.h> 
#include<stdio.h> 
#include<fcntl.h> 
  
int main() 
{ 
    int file_desc = open("tricky.txt",O_WRONLY | O_APPEND); 
      
    // here the newfd is the file descriptor of stdout (i.e. 1) 
    dup2(file_desc, 1) ;  
          
    // All the printf statements will be written in the file 
    // "tricky.txt" 
    printf("I will be printed in the file tricky.txt\n"); 
      
return 0; 
} 

printf的輸出會寫入tricky.txt中