Refactor to use dispatch_io for tasks, and wait for EOF

Hopefully resolves #139, #135, #161.

/cc @joshaber @keithduncan
I was under the impression that `dispatch_io` would/could manage the FD for us; is that mistaken, or is that not the case here because we open it ourselves?