为什么我不能“freopen”一个“tmpfile”?

我试图编译并运行有以下几行的C代码:

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 dump:

 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) 

从C99标准:

freopen函数打开名称是filename指向的string的文件,并将stream指向的stream与它关联。 mode参数和fopen函数一样。

如果filename是一个空指针,freopen函数会尝试将stream的模式更改为mode指定的模式,就好像当前与stream相关联的文件的名称已被使用。 它是实现定义模式的变化是允许的(如果有的话),以及在什么情况下。

所以,可能是谁编写了这个代码,意味着将临时文件打开模式从w+b更改为r+ (主要归结为将stream更改为文本模式)。 不幸的是,在你的实现中似乎不可能以这种方式改变临时文件的打开模式。

我想这可能来自closures一个临时文件也删除它的事实,但也可能是glibc实现不支持freopen中的模式更改(manpage甚至没有提到传递NULL的可能性第一个参数)。

Interesting Posts