[WIP] implement system() with pipes, on top of os_system() on top of job_wait()

So this is attempt 2 with hopefully less code duplication. For attempt 1 and its discussion, see #807.

I would like to request @tarruda to look over this code, while it's WIP because he knows the job architecture best and in many cases I'm not at all sure if I've made the best decisions. Ignore the logging statements for now please.

Preliminary results (thanks to @shougo for the benchmark script):

```vim
let cnt = 50

let start = reltime()

for i in range(1, cnt)
  " 13MB file
  call system('cat song.flac')
endfor

echomsg 'system()         = ' . reltimestr(reltime(start))
```

~~I compile on release mode (otherwise the benchmark doesn't even work, yes that's strange and it worries me too). Neovim master doesn't show this problem, so it's been introduced somewhere in these commits. I can only think of  the `ELOG`'s, but standard neovim also produces logs.~~ (fixed: it was the logs, because the read stream or libuv only reads 1024 bytes at a time, the log was getting swamped and making my computer do very strange things. I even think that I could input keys and exit vim while this was happening because I'm returning too early from `job_wait()`, but @tarruda will have to confirm that. In reality I don't see how it can happen though, `system_out_cb` shouldn't be called after the job exits, at all).

```bash
$ make CFLAGS='-flto -DNDEBUG -march=native' CMAKE_EXTRA_FLAGS='-DCMAKE_BUILD_TYPE=MinSizeRel' DEBUG=0
```

I run it with:

```bash
$ $VIM -u NONE -U NONE -E -c "source bench.vim"
```

- Vanilla vim: ~12.5 sec (somehow, it's faster than master here, usually it isn't)
- Neovim master (optimized): ~14 sec
- Neovim on pipes (optimized): ~4 sec (quite a bit better, difference not very obvious for small commands)

I have no idea if that's the best way to do it. If someone knows a better way, I'm all ears.

To compare with some sort of baseline, I do:

```bash
# can't do "cat song.flac > /dev/null" because it seems cat is being clever and does nothing
# which is why I create a ramdisk...
$ diskutil erasevolume HFS+ 'aramdisk' `hdiutil attach -nomount ram://131072`
$ time (for run in {1..50}; do cat song.flac > /Volumes/aramdisk/song.flac; done)
0,10s user 1,37s system 92% cpu 1,592 total
```

**EDIT**: I would love to receive other peoples benchmark results too.
~~**EDIT 2**: As some will notice, when compiling in DEBUG mode the benchmark doesn't work. I'm not sure why yet.~~
**EDIT 3**: it should be a little slower than the approach in #807, as the `rstream` has an intermediate buffer (which means redundant copying happens, the data gets copied once in #807, but twice in this PR). It's still better than writing and reading from a temporary file though.
> We can't inherit the parent's std{out,err} because it won't work for UIs over msgpack-rpc.

I didn't mean inheriting the parent's (nvim)'s stdout/stderr, I meant not opening the pipes at all. That way there could never be any data to read (and the process could also known that it's not expected to output anything). Not sure what the OS does if the process tries to write to such an FD. Perhaps send it to /dev/null efficiently.

> You might need to create a struct that encapsulates the dynamic buffer and the os_system options, and pass it as the job data to handle the job callbacks correctly.

I'm really not sure why that would be necessary, it works fine as is. Can you give an example?