[RDY] implement system() with pipes

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.
Fixed.


On Thu, Jul 24, 2014 at 10:44 AM, oni-link <notifications@github.com> wrote:

> In src/nvim/os/wstream.c:
>
> > @@ -83,6 +87,25 @@ void wstream_set_stream(WStream *wstream, uv_stream_t *stream)
> >    wstream->stream = stream;
> >  }
> >
> > +/// Sets a callback that will be called on completion of a write request,
> > +/// indicating failure/success.
> > +///
> > +/// This affects all requests currently in-flight as well. Overwrites any
> > +/// possible earlier callback.
> > +///
> > +/// @note This callback will not fire it the write request couldn't even be
>
> typo it -> if
>
> —
> Reply to this email directly or view it on GitHub
> <https://github.com/neovim/neovim/pull/978/files#r15335720>.
>