I'm working on a small Rust cli project, which involves having to deal with some relatively low level details of how processes interact between them.
In POSIX-compatible systems, shells usually pass their "standard" file descriptors to their child: stdin (0), stdout (1), and stderr(2); and many other non-shell processes do the same as well (and, when they are not inherited from the parent process, it's usually because we have pipes involved).
The problem is that, although the most usual case, that might not hold all the time, and we could have some processes without some of these file descriptors available.
As far as I can see, in Rust we have the method std::io::stdin that returns as a struct that allows us to "directly" interact with stdin... and it seems it assumes that stdin will be always there (given that it does not return a Result struct, but directly a Stdin reference).
How can we check in a safe way if stdin is really available?
Just out of curiosity, I've been digging around on the internet trying to figure out what you're asking. I don't really understand why you're talking about file descriptor inheritance, when you're trying to understand if a file discriptor is available, because file descriptors can easily be redirected to point to other files. I don't really know what you mean when you say that some file descriptors might be unavailable... IIRC, A file descriptor is basically just a number that indicates an open file. Are you trying to determine if the file is closed? You might be able to use something like fcntl to detect if the file associated with a file descriptor is in a good state...
But it might be better to just attempt a read and see if you get an error.
The child inherits the parents open files, the file descriptors are unique to the child. The child's fd 0 always points to their own stdin, regardless of whether or not that ends up pointing to the same file as the parent.
I don't think any unix program handles this. Even graphical programs have at least stdout and stderr open. Usually it is ~/.xsession-errors. I am not sure about stdin though, but I suspect it has /dev/null open.
This will obviously be platform-specific, but on Linux machines the /proc/self/fd/ directory will list all open file descriptors for the current program. You can also use /proc/$PID/fd/ for checking arbitrary processes by PID.