A variant of the question Getting Filename from file descriptor in C. This is 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 as where it lives, of course)? I'm looking for something similar to rename(2) or link(2) but that would accept a file descriptor as input instead of a file name.
The problem with rename(2) and link(2) is that even though you can attempt to go from the file descritor to the file name, this might fail. I'm thinking more precisely about the case where the opened file descriptor refers to a file that was already unlinked --- in this case, the file has no more name. It seems that there is no way to prevent the file from being deleted when we close() the file descriptor. But am I wrong? Can we, with the Posix or even Linux API, give it a name again?
Update: we can actually see the content of a deleted file on Linux in /proc/<pid>/fd/<fd>
, even though it looks like a broken symbolic link. We can't use link(2) or ln(1) to rematerialize such a file, though, because it thinks we're trying to do a cross-device link.
Right-click the file and select Rename. Enter a new file name and press Enter.
Method one. Highlight the file or folder. Right-click the file with your mouse and select Rename from the menu that appears.
No it is not. PID is process identifier, and file descriptor is file handler identifier.
If the question is about linux, and about linux > 2.6.39, you can use the linkat
command with the AT_EMPTY_PATH
flag to give a name to a file descriptor. See the man page (http://man7.org/linux/man-pages/man2/link.2.html)
linkat(fd,"",destdirfd,"filename",AT_EMPTY_PATH);
Caveats:
_GNU_SOURCE
to get the definition for AT_EMPTY_PATH
, If this were to fail, you have no other chance than to create a new file and copy the content over it using sendfile
(error checking omitted, see man 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);
Question: a hypothetical system call frename
that takes a file descriptor existed, and if a file has multiple names (hard links), which of those names would get moved/renamed when this system call was used on a file descriptor that refers to this file?
There is no good answer to that question, and that's one of the reasons this system call does not exist.
rename
deals with directory entries, which are pointers to files (inodes). An open file descriptor is not associated with any particular directory entry, only with the file itself (the inode). From that perspective, the system call you are asking for doesn't really make sense. There is no portable way to follow an inode back to the directory entry that points to it (and, again, there might be more than one of them). Some operating systems may provide various non-portable means for finding this backward link which may or may not be guaranteed to always come up with a result (usually not guaranteed), but these means don't answer the question of which directory entry to return when there is more than one, and to my knowledge none of them have been extended into a system call like what you're looking for.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With