I see where I went wrong.
To give a more concise answer to this question, I got the code to run and saw the results just as you reported. So I started experimenting.
I noticed there are a lot of operations on references happening here, which makes me leery when you're mucking with global symbols (STDOUT, for instance). So I took $output and gave it persistence in scope:
our $output ; # changed 'my' to 'our'
The problem went away.
By the way, I agree with the monks who suggested using select().
Peace, monks.