12 dup函式和dup2函式

2021-08-21 00:19:10 字數 3724 閱讀 2254

當呼叫dup函式時,核心在程序中建立乙個新的檔案描述符,該檔案描述符是當前可用檔案描述符的最小數值,這個檔案描述符指向oldfd所擁有的檔案表項。

函式原型:

#include 

int dup(int oldfd);

引數說明:oldfd為已經開啟的檔案描述符

返回值:成功返回乙個新檔案描述符,失敗返回-1並設定errno

使用dup函式複製乙個已經開啟檔案的檔案描述符

圖1-dup函式

#include 

#include

#include

#include

#include

int main(void)

//此時開啟乙個檔案的描述符是3

printf("fd = %d\n", fd);

//fd是當前開啟的檔案的描述符

int newfd = dup(fd);

if(newfd == -1)

//此時0,1,2,3都被占用了,可用的最小檔案描述符是4

//所以newfd指向fd所擁有的檔案表項,newfd = 4

printf("newfd = %d\n", newfd);

char buf1 = "fd : hello\n";

char buf2 = "newfd : world\n";

//然後都向newfd和fd指向的檔案中寫資料

write(fd , buf1 , sizeof(buf1));

write(newfd , buf2 , sizeof(buf2));

return

0;}

執行結果:

通過write函式向newfd和fd指向的檔案中寫資料,然後再檢視test.txt檔案裡的內容,發現newfd和fd兩個檔案描述符都指向了test.txt檔案。

假如fd1的值為1,當前檔案描述符表中最小可用的檔案描述符是3,那麼新檔案描述符3指向檔案描述符1所指向的檔案,相當於fd2會複製fd1。

函式原型:

#include 

int dup2(int fd1, int fd2);

引數說明:

fd1為已經開啟的檔案描述符

fd2為新的檔案描述符(fd1拷貝到fd2)

返回值:成功返回乙個新檔案描述符,失敗返回-1並設定errno

使用dup2函式複製乙個已經開啟檔案的檔案描述符

圖2-dup2函式

#include 

#include

#include

#include

int main(void)

printf("--------dup2之前--------\n");

//此時開啟乙個檔案,描述符是3

printf("oldfd = %d\n", oldfd);

//再開啟乙個test2檔案,描述符是4,同時newfd指向test2.txt檔案

int newfd = open("test2.txt", o_rdwr);

if(newfd == -1)

printf("newfd = %d\n", newfd);

/* oldfd是當前開啟的檔案的描述符,此時dup2函式會把oldfd檔案描述符拷貝給newfd,

之前我們學過檔案描述符的本質實際是乙個指標去指向檔案,

oldfd拷貝到newfd這個過程就是把oldfd指向檔案的位址給了newfd,然後newfd

也指向了這個檔案,同時newfd斷開了之前指向的檔案

*/printf("--------dup2之後--------\n");

newfd = dup2(oldfd , newfd);

if(newfd == -1)

printf("newfd = %d\n", newfd);

char buf1 = "oldfd : hello\n";

char buf2 = "newfd : world\n";

//然後都向newfd和oldfd指向的檔案中寫資料

write(oldfd , buf1 , sizeof(buf1));

write(newfd , buf2 , sizeof(buf2));

return

0;}

執行結果:

從圖中執行結果來看,在呼叫dup2之前,oldfd指向test1.txt檔案,newfd指向test2.txt檔案,在呼叫dup2之後,關閉newfd對test1.txt檔案的指向,轉而指向了test1.txt檔案,然後檢視test1.txt檔案的內容也說明了newfd確實指向了test1.txt檔案。

dup和dup2都是複製現有的乙個檔案描述符實現檔案共享時,但是無論複製出多少個檔案描述符,這些檔案描述符都只共享乙個檔案表,所以使用所有描述符去操作檔案時,使用的都是共享檔案表中的同乙個檔案位移量,只要對檔案進行讀寫操作時就會更新檔案表中的檔案位移量,因此就不會出現資料覆蓋

我們可以通過下圖來說明dup和dup2是如何實現檔案共享的。

圖3-dup和dup2實現檔案共享

從圖3來看,檔案描述符3和4共享乙個檔案表,說明3和4指向了同乙個檔案,任何乙個檔案描述符對檔案進行讀寫操作都會更新檔案表中的f_pos的值,也就是共享f_pos位置,這樣就不會出現資料覆蓋。

現在通過dup2函式來實現乙個cat命令的程式,實現cat file1 > file2 命令相似功能。

#include 

#include

#include

#include

#include

//封裝錯誤資訊

void sys_err(int fd, char *err_name)

}int main(void)

//阻塞讀取終端

while ((ret = read(stdin_fileno, buf, sizeof(buf))))

//從file2讀取資料1024位元組到buf中

while ((ret = read(fd_f2, buf, sizeof(buf))))

//關閉流

close(fd_f1);

close(fd_f2);

close(fd_out);

return

0;}

dup和dup2的區別在於:

1. dup 返回的新檔案描述符是當期程序的檔案描述符表中最小可用的檔案描述符

2. dup2的fd2可以指定新描述符的數值,比如:fd2已經開啟乙個檔案,則會先關閉fd2,如果fd2 = fd1的話,那麼返回fd2。

Linux中dup函式和dup2函式

個人部落格傳送門 linux 中進行檔案描述符的重定向可以使用兩個函式 dup函式和dup2函式,其中還有乙個dup3函式,但是這個是linux後面版本新增的,不是所有的linux核心都支援,在這裡不討論。在linux系統中約定檔案描述符 0 1 2 對應標準輸入 標準輸出 標準錯誤,預設開啟。du...

重定向程式設計 dup和dup2函式

輸入重定向 關閉標準輸入裝置,開啟 或複製 某普通檔案,使其檔案描述符為0.輸出重定向 關閉標準輸出裝置,開啟 或複製 某普通檔案,使其檔案描述符為1.錯誤輸出重定向 關閉標準錯誤輸入裝置,開啟 或複製 某普通檔案,使其檔案描述符為2.1.dup函式 返回值 如成功則返回新的檔案描述符,否則出錯返回...

Unix 下dup和dup2函式的解析

函式原型 include int dup int filedes int dup2 int filedes,int filedes2 apue上說dup返回最小的可用檔案描述符 最小的尚未開啟的檔案 對於dup2,我們指定新的檔案描述符引數為filedes2。如果filedes2已經開啟,那麼它將先...