从文件描述符重命名?

时间:2012-12-13 14:00:12

标签: posix rename

问题Getting Filename from file descriptor in C的变体。这是关于Linux的。

如果我有一个引用常规文件的文件描述符,我可以通过给它一个新的文件名“保存”文件描述符(当然,它在同一设备上的某个地方)?我正在寻找类似于重命名(2)或链接(2)的东西,但是它会接受文件描述符作为输入而不是文件名。

重命名(2)和链接(2)的问题在于,即使您可以尝试从文件descritor转到文件名,这可能会失败。我正在更准确地考虑打开的文件描述符引用已经取消链接的文件的情况 - 在这种情况下,文件没有更多名称。当我们关闭()文件描述符时,似乎无法阻止文件被删除。但我错了吗?我们可以使用Posix甚至Linux API再次命名吗?

更新:我们实际上可以在/proc/<pid>/fd/<fd>中看到Linux上已删除文件的内容,即使它看起来像一个破损的符号链接。但是,我们不能使用link(2)或ln(1)来重新实现这样的文件,因为它认为我们正在尝试进行跨设备链接。

2 个答案:

答案 0 :(得分:4)

如果问题是关于linux,关于linux&gt; 2.6.39,您可以使用带有linkat标志的AT_EMPTY_PATH命令为文件描述符指定名称。请参见手册页(http://man7.org/linux/man-pages/man2/link.2.html

linkat(fd,"",destdirfd,"filename",AT_EMPTY_PATH);

注意事项:

  • 您需要定义_GNU_SOURCE以获取AT_EMPTY_PATH
  • 的定义
  • 对于链接数为零的文件,不保证可以正常工作。我不确定我是否理解手册页中有关此内容的内容。我的猜测是,当文件的链接数为零时,文件系统上的inode已被删除,以避免文件系统崩溃时的不一致。
  • 当然,如果旧文件不在目标目录的同一文件系统上,我不希望它能够正常工作。

如果失败,除了创建新文件并使用sendfile复制内容之外没有其他机会(错误检查省略,请参阅每个函数的手册页以获取可能的错误值):< / p>

struct stat s;
off_t offset = 0;
int targetfd = open("target/filename", O_WRONLY | O_CREAT | O_EXCL);
fstat(fd,&s);
sendfile(targetfd,fd,&offset, s.st_size);

答案 1 :(得分:3)

问题:一个假设的系统调用frename,它存在一个文件描述符,如果一个文件有多个名称(硬链接),那么在这个系统调用被用于某个名称时会被移动/重命名引用此文件的文件描述符?

这个问题没有一个好的答案,这就是这个系统调用不存在的原因之一。

rename处理目录条目,它是指向文件(inode)的指针。打开的文件描述符不与任何特定的目录条目相关联,只与文件本身(inode)相关联。从这个角度来看,你要求的系统调用并不真正有意义。没有可移植的方法将inode追溯到指向它的目录条目(并且,同样,可能存在多个inode)。某些操作系统可能提供各种非便携式方法来查找这种后向链接,这种方法可能会或可能不会保证总能得出结果(通常不能保证),但这些方法无法回答返回哪个目录条目的问题当有多个时,据我所知,它们都没有扩展到你正在寻找的系统调用中。