Because fdopen() closes the file handle first the code: freopen("/dev/stdin", "r", stdin) fails -- /dev/stdin can't be opened. If it opened a new file descriptor first and then closed this would work. The real need is simple minded programs that naively use freopen() and then use stdin or stdout.
Don't do it then? There is a standard POSIX supported way of doing this, just pass NULL as the first argument to freopen.
That works if you are writing a C program. If someprogram that uses freopen() and you give it a command line argument of /dev/stdin, expecting it to process stdin, you will get a nasty surprise. For this to work the program itself would need to specially recognise /dev/stdin and /dev/fd/0 and .... I am trying to make life easy for the application writer.
(In reply to comment #2) > I am trying to make life easy for the application writer. By adding undue burden which negatively impacts everybody who doesn't need to use this nonstandard way? And the fact that the behavior is implemented like this for 10+ years shows it is not (widely) used. The standard is very clear: The freopen() function shall first attempt to flush the stream and close any file descriptor associated with stream. The descriptor is closed and *then* we work on opening the new file.
I quite agree that the freopen() manual is very clear, but a user of an application is not going to read that. They will read the application manual that will say something like: foobar <inputFile> <outputFile> and so expect to type: someCommand | foobar /dev/stdin /tmp/SomeOutputFile There are a few programs that have that sort of syntax, they don't work with /dev/stdin.