posix/shell: Add posix `read()` and `write()`

This diff implements the functions `read()` and `write()` for RIOT file
descriptors.

A file descriptor now contains a single pointer to the file operations
in order to easify the interface, make RIOT more forward compatible, and
conserve a few bytes.

~~An unused file descriptor now stores a pointer to the next unused FD, so
allocating a new FD becomes an `O(1)` time operation, instead of
`O(FD_COUNT)`.~~