2012-08-27 39 views
1

我有一個打開的設備描述符,其中我不知道設備名稱以及傳遞給打開(...)的選項 。 我想用打開的相同選項打開一個新的設備描述符。使用與參考描述符相同的選項打開新的設備描述符

int newFd = copy(referenceFd); 

其中副本可以完成這項工作。 dup()肯定是錯誤的選擇,因爲newFd上的進一步ioctl()也會改變referenceFd,因此我想打開一個新的描述符。

是否有系統調用提供此類功能?
我還找不到東西。

回答

1

首先,使用

int flags = fcntl(fd, F_GETFL); 

然後得到文件描述符fd的文件描述符標誌,重新打開使用Linux的特定描述符/proc/self/fd/fd項:

int newfd; 
    char buffer[32]; 

    if (snprintf(buffer, sizeof buffer, "/proc/self/fd/%d", fd) < sizeof buffer) { 
     do { 
      newfd = open(buffer, flags & ~(O_TRUNC | O_EXCL), 0666); 
     } while (newfd == -1 && errno == EINTR); 
     if (newfd == -1) { 
      /* Error: Cannot reopen file. Error in errno. */ 
     } 
    } else { 
     /* Error: the path does not fit in the buffer. */ 
    } 

重新開放的文件描述符然後在newfd

請注意,您很可能希望確保O_TRUNC(截斷文件)和O_EXCL(如果存在故障)不在標誌,避免出現使用完全相同的原始標誌會導致不想要的結果重新打開案件。

你做想用lstat(),因爲這對於開闢了競爭條件重命名 - 用戶重命名lstat()並在上面的代碼open()的目標文件。以上完全避免了這一點。

如果你不希望成爲Linux特有,添加試圖同與/dev/fd/fd如果上述失敗的代碼。它在一些Unix系統(也是大多數Linux發行版)中得到了支持。

+0

非常感謝。我會嘗試 –

3

,也許可以與一系列fcntl calls做到這一點:

F_GETFD - 取得了與文件描述符fildes關聯定義文件描述符標誌。

F_GETFL - 獲取與fildes相關的文件描述中定義的文件狀態標誌和文件訪問模式。

我鏈接上面的SUSv4頁面;您可能也有興趣the Linux version

+0

看來,在F_GETFD設備名稱不存儲?否則,我怎麼能第二次打開設備,所以我可以用fcntl設置標誌? –

+1

@the_summer:如果你不介意搞亂Linux的細節,你可以''在'/ proc/self/fd'中指定fd,這會得到設備名稱 – Hasturkun