Yes it can. Via /proc/$pid/fd/$fd
.
Example:
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int fd;
if(0>(fd = open("DELETED", O_CREAT|O_RDWR|O_CLOEXEC, 0600))) return perror("open"),1;
static char const msg[]="got me\n";
(void)write(fd, msg, sizeof(msg));
if(0>(unlink("DELETED"))) return perror("unlink"),1;
char buf[128];
sprintf(buf,"cat /proc/%ld/fd/%d", (long)getpid(), fd);
system(buf);
}
(Here I'm accessing it from a(n indirect) child process, but this is not a requirement. It works from unrelated processes as well.)
The /proc/$pid/fd/$fd
items appear as symlinks in the filesystem.
They usually point to the name the file was opened as but when the file is deleted, the original link target has a " (deleted)"
appended to it as in
lrwx------ 1 petr petr 64 Aug 19 12:45 /proc/32027/fd/3 -> '/home/petr/DELETED (deleted)'
yet in spite of such a target being nonexistent such a proc symlink works (through some dark kernel magic, presumably).