2013-11-23 35 views
0

我試圖編譯和運行具有以下行的C代碼:爲什麼我不能「freopen」一個「tmpfile」?

FILE *preproc_producer = NULL; 
preproc_producer = tmpfile(); 
// preproc_producer is not NULL here 
preproc_producer = freopen(NULL, "r+", preproc_producer); 
// preproc_producer is NULL here 

但是,當運行代碼時,preproc_producer結束NULL,和錯誤代碼是Stale NFS file handle

  1. 什麼問題與上述代碼?

  2. 調用freopen的目的是什麼?我註釋掉了freopen這一行,其他程序似乎正在工作。

我使用GCC 4.7.2,在Docker 0.6.7 Linux容器內運行Ubuntu 64 12.04。上面的代碼似乎在Docker容器之外工作。

更新: strace的轉儲:

stat("/tmp", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=4096, ...}) = 0 
gettimeofday({1385247432, 199732}, NULL) = 0 
getpid()        = 127 
open("/tmp/tmpf9l14HD", O_RDWR|O_CREAT|O_EXCL, 0600) = 3 
unlink("/tmp/tmpf9l14HD")    = 0 
fcntl(3, F_GETFL)      = 0x8002 (flags O_RDWR|O_LARGEFILE) 
brk(0)         = 0xc94000 
brk(0xcb5000)       = 0xcb5000 
fstat(3, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0 
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7afb9d0000 
lseek(3, 0, SEEK_CUR)     = 0 
lstat("/proc/self/fd/3", {st_mode=S_IFLNK|0700, st_size=64, ...}) = 0 
munmap(0x7f7afb9d0000, 4096)   = 0 
open("/proc/self/fd/3", O_RDWR)   = -1 ESTALE (Stale NFS file handle) 
+1

NULL意味着失敗,否則返回的流指針已經「打開」... http://www.cplusplus.com/reference/cstdio/tmpfile/ –

+0

在'strace'中運行你的程序,看看會發生什麼。如果freopen()不得不關閉文件來改變訪問模式,我不希望這會起作用,因爲tmpfile()在關閉時會被刪除。 – nos

+1

查看['freopen()']的POSIX規範(http://pubs.opengroup.org/onlinepubs/9699919799/functions/freopen.html)。你應該在調用之前設置'errno = 0;',然後在重新打開時無法確定爲什麼失敗時檢查'errno'。從表面上看,沒有任何理由說明代碼不適用。同樣,沒有明顯的原因,你首先需要'freopen()'。確實是 –

回答

3

C99標準:

調用freopen函數打開,其名稱是指向的字符串的文件名 和相關聯的流指向的文件通過與它流。與fopen函數一樣,mode參數只用於 。

如果filename是空指針,freopen函數會嘗試將流的模式更改爲mode指定的模式,就好像當前與 流相關聯的文件的名稱已被使用。它是實現定義哪種模式更改允許(如果有的話)以及在什麼情況下允許的 。

所以,大概誰寫這段代碼的意思改變從w+br+臨時文件的打開方式(這主要是歸結爲改變流文本模式)。不幸的是,在你的實現中,似乎不可能以這種方式改變臨時文件的打開模式。

我想,它可能來自於一個事實,即關閉臨時文件也刪除它,但它也可能是glibc實施freopen不支持在freopen模式的改變(手冊頁甚至沒有提到的可能性作爲第一個參數傳遞NULL)。

+0

。 freibn()在glibc文檔中關閉了現有的流。對於tmpfile()這意味着文件也被刪除。 – nos

+0

我加了strace。失敗在'open(「/ proc/self/fd/3」,O_RDWR)'上。也許這是一個文件系統問題? –

相關問題