it seems to ignore the input stream
ls program never uses the input stream, because it wasn't written to read anything from the input stream. This is not something that comes automatically with any Unix program – it has to be implemented separately.
Do not confuse the input stream (stdin) with the command-line arguments (argv); the former is an actual stream which can be read from line-by-line, while the latter is a simple read-only array of words. In your case, both are present and contain different data.
(Why shouldn't it be automatic for all programs? Well, take sort or cat or grep as an example. These programs accept different kinds of values – file names as arguments, but text as stdin contents. So you can pipe any command to
| sort, and it sorts the input. But if stdin and command-line were the same thing, you couldn't pipe anything into
| sort anymore because it would think that the pipe input was a list of filenames. Or vice versa, you couldn't give it filenames because it'd just sort the names.)
For an alternative take, see this explanation on StackOverflow (which you already got in the comments).