[WIP] Refactor to use dispatch_io for tasks, and wait for EOF

Hopefully resolves #151, #139, and #135.

/cc @joshaber @keithduncan
`NSTask` is pretty clear that setting a custom handle for `standardOutput` and `standardError` could cause problems, because the correct ends of the pipe won't always be closed.

I'm not sure that we can handle it ourselves either, because we don't “know” whether `NSTask` will fork or not. I assume that this is why it accepts `NSPipe`—so it can control both ends as appropriate.