A symbolic link is a small file that contains the name of the target file, with a flag in the directory entry indicating that it's a symlink.
When you open a symlink, the OS resolves the name of the target file. If the target itself is a symlink, it resolves its name as well; there's a limit on the number of levels. (Things get a bit more complex if the name in the symlink is a relative path.)
Once the name is resolved to the name of a file that's not a symlink, that file is opened normally. The open filehandle or descriptor refers to the file itself, not to the symlink that was used to open it, and not even to the directory entry that contains its actual name. Once a program has the file open, changing the name, changing the symlink, or even unlinking the file has no effect on the program; it's still reading the same file.
Most operations treat a symbolic link as if it were the actual file that it refers to. The
readlink() system call is an exception to this; it reads the contents of the symlink itself. The
lstat() system call is like
stat(), except that it returns information on the symlink itself rather than on the file it refers to.
Note that the
rm command or the
unlink() system call doesn't necessarily physically remove a file; it removes its directory entry. The file itself is removed when there are no more directory entries (hard links) that refer to it, and when no process has the file open.