If I’ve got a handle to an open file, is it possible to create a hard link to that file after all references to it have been removed from the filesystem?
For example, something like this:
fd = fopen("/tmp/foo", "w"); unlink("/tmp/foo"); fwrite(fd, "Hello, world!n"); create_link_from_fd(fd, "/tmp/hello"); fclose(fd);
Specifically, I’d like to do this so that I can safely write to large data files, then move them into place atomically without having to worry about cleaning up after myself if my program is killed in the middle of writing the file.
Advertisement
Answer
Not generally, no. [Edit: since Linux 3.11 there is now linkat
; see safsaf32’s answer. This does not work on POSIX systems in general since POSIX linkat
is restricted to directories only.] There are security considerations here: someone can pass to you an open file descriptor that you could not normally open
on your own, e.g.:
mkdir lock; chmod 700 lock echo secret contents > lock/in sudoish cmd < lock/in
Here cmd
runs as a user who has no permission to open
the input file (lock/in
) by name, but can still read from it. If cmd
could create a new name on the same file system, it could pass the file contents on to a later process. (Obviously it can copy those contents, so this issue is more of a “pass the contents on by mistake” thing than “pass the contents on, on purpose”.)
That said, people have come up with ways of “relinking” files by inode/vnode internally (it’s pretty easy to do inside most file systems), so you could make your own private system call for it. The descriptor must refer to a real file on the appropriate mount point, of course—there’s no way of “relinking” a pipe or socket or device into becoming a regular file.
Otherwise you’re stuck with “catch signals and clean up and hope for the best”, or a similar trick, “fork off a subprocess, run it, and if it succeeds/fails, take appropriate move/clean-up action”.
Edit to add historical note: the above lock
example is not particularly good, but back in the days of V6 Unix, MDQS used a fancier version of this trick. Bits and pieces of MDQS survive in various forms today.