2015-06-13 117 views
1

我偶然發現了一個正在處理的程序中的問題。下面再現我的問題:調用fdopendir()破壞文件描述符

#include <stdlib.h> 
#include <stdio.h> 
#include <errno.h> 

#include <sys/types.h> 
#include <dirent.h> 
#include <fcntl.h> 
#include <sys/stat.h> 

int main(int argc, char *argv[]) 
{ 
    int fd, ret_fd; 
    DIR *dirp; 
    fd = open("./", O_RDONLY); 

#if 1 
    if ((dirp = fdopendir(fd)) == NULL) { 
     perror("dirp"); 
     return 1; 
    } 
    closedir(dirp); 
#endif 

    ret_fd = openat(fd, "Makefile", O_RDONLY); 
    if (ret_fd == -1) { 
     perror("ret_fd"); 
     return 1; 
    } 
    return 0; 

} 

基本上,調用openat(),已通過preceeded fdopendir(),失敗:Bad file descriptor。但是,如果省略fdopendir(),則不會發生這種情況。

我知道fdopendir()使內部使用的文件描述符,但它不應該在調用closedir()後恢復對它的任何更改嗎?

如何避免openat()在這種情況下失敗?

回答

4

fdopendir()POSIX description說:

在調用closedir()的文件描述符將被關閉。

因此,描述符可能會在您撥打openat()時關閉。

這是從a typical Linux man pagefdopendir():

成功調用後fdopendir(),FD由 實現內部使用,而不應以其他方式應用程序使用。

+1

請注意,爲避免這種情況,您只需在將文件描述符傳遞給'fdopendir之前先'dup' '。 –

2

這樣的:

closedir(dirp); 

也隱含地關閉文件描述符。

+0

我明白了。謝謝,我的壞。 – Alexguitar

+1

當你回答時,我只想評論一下:看看這個例子,這一行中的評論'closedir(d); //注意這隱含地關閉了dfd' http://pubs.opengroup.org/onlinepubs/9699919799/functions/fdopendir.html –