[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.
> For now you could change the job module to redirect to /dev/null when a NULL callback is passed(UV_IGNORE flag or the process would hang when the OS buffers get full), but eventually I want to use os_system instead of os_call_shell which is called by filter commands, and this would require displaying command output when no output argument is passed

Perhaps I misunderstood you earlier and you knew that `UV_IGNORE` redirects to `/dev/null`. Why would you pass `NULL` to `output` if you want to display the output? I don't fully understand.