The Linux kernel tracks one file descriptor table ( struct fdtable ) for each process ( more or less ). The entries in this table are indexed by small integers - starting with 0, 1, 2, etc. The newest entries are assigned the smallest available integer and each points to one open file ( struct file ).
A file in the Linux kernel is a handle to a descriptor ( struct inode ) and some state (for example, a search position).
If you open the same file several times, you will have several entries in the file descriptor table, each of which points to different file structures, each of which points to the same structure of the inode.
If you open the file and then the dup file descriptor, you will have several entries in the file descriptor table, each pointing to the same file structure.
Creating a pipe results in two file descriptors: the end of reading and the end of writing. They are somewhat magical: reading from the first file descriptor will return the data that was written to the second file descriptor. At the time of creation, both ends of the pipe are available only for this process.
Transferring the file descriptor to another process (which is usually done by sendmsg via AF_UNIX with the auxiliary SCM_RIGHTS attached, but on Android it runs Binder.transact with Parcel.writeFileDescriptor ), a new record is added to the file descriptor table of the receiving process, indicating the same file structure as and the original entry in the descriptor table file of the sending process. NB: the integer index for the same file in two processes is not connected; In fact, this is likely to be different.
Usually in C you use fopen to get a FILE * structure, which you can fread / fwrite / etc. on the. The C runtime library does this by opening the file descriptor and wrapping it with a structure (which contains additional buffering, etc.). fdopen accepts a file descriptor that is already open in the local process, and the FILE * structure around it.
Addition of parts:
No other process can open a file, guessing the FD number, because these numbers make sense in only one process. * Transferring a file descriptor between processes is safe, mediated by the kernel, which manages objects that only the kernel accesses.
* Given the appropriate privileges, you can go through the pseudo file system /proc/$PID/fd/$FD to find the file descriptors of other processes and rediscover them for yourself. However, the “corresponding privileges” are “the same user or root”. On Android, all applications work as different users, and not one of them runs as root - this is impossible. In addition, SELinux Android policies do not allow applications to interact with /proc interfaces.