Rename from file descriptor?

Variant of the question Getting the file name from the file descriptor in C. It's about Linux.

If I have a file descriptor that refers to a regular file, can I “save” the file descriptor by giving it a new file name (somewhere on the same device where it lives, of course)? I was looking for something similar to renaming (2) or link (2), but which would take the file descriptor as an input name instead of a file name.

The problem with renaming (2) and link (2) is that even if you can try to switch from the descritor file to the file name, it may fail. I think more precisely about the case when an open file descriptor refers to a file that has already been disconnected - in this case, the file no longer has a name. There seems to be no way to prevent file deletion when closing () the file descriptor. But am I wrong? Can we with Posix or even the Linux API give it a name again?

Update: we can actually see the contents of the remote file on Linux in /proc/<pid>/fd/<fd> , although it looks like a broken symbolic link. We cannot use link (2) or ln (1) to remake such a file, though, because he thinks we are trying to link to several devices.

+8
posix rename
source share
2 answers

If the question about Linux and Linux> 2.6.39, you can use the linkat command with the AT_EMPTY_PATH flag to give a name to the file descriptor. See the man page ( http://man7.org/linux/man-pages/man2/link.2.html )

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

Cautions:

  • You need to define _GNU_SOURCE to get the definition for AT_EMPTY_PATH ,
  • For files with a reference of zero, this is not guaranteed. I'm not sure I understand what this says on the man page. I assume that when a file has zero links, the inode is already deleted on the file system to avoid inconsistencies if the file system should have failed.
  • Of course, I do not expect this to work if the old file is not in the same file system in the destination directory.

If this was unsuccessful, you have no other chance than creating a new file and copying the contents on top of it using sendfile (a validation error is omitted, see the help pages of each function for possible error values):

 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); 
+3
source share

Question: there is a hypothetical frename system call in which a file descriptor exists, and if the file has several names (hard links), which of these names will be moved / renamed when this system call was used in the file descriptor does this apply to this file?

There is no good answer to this question and that one of the reasons for this system call does not exist.

rename processes directory entries that are pointers to files (inodes). An open file descriptor is not associated with any particular directory entry, only with the file itself (inode). From this point of view, the system call you are asking for does not really make sense. There is no portable way to follow an inode back to a directory entry that points to it (and, again, there may be more than one of them). Some operating systems may provide various intolerable means for finding this backlink, which may or may not be guaranteed to always come up with a result (usually not guaranteed), but these tools do not answer the question of which directory entry should be returned when there is more than one, and as far as I know, not one of them was expanded into a system call like what you are looking for.

+2
source share

All Articles