Switch to using exec() to start worker processes

Our older (and slightly faster) technique of doing a fork() and then
transforming the running Python interpreter into a worker through an
exception turns out to have had a fatal drawback: as the "turn into a
worker" exception propagated out to the top level, it would run exit all
of the enclosing context managers, closing and destroying resources that
the main process probably wanted to keep around!
Configure TTY for keystroke-at-a-time I/O