After you type the two Ctrl-D (EOT), your programm will only receive NUL-bytes. And an infinity of them. Unfortunately you have an unconditional read in an infinite loop. Either you change that (e.g. give the user a lesson if he types something other than q
or e
and exit if he didn't get it after the third try), or you implement control characters correctly. Your module strips all control characters from the input before you even get it, but it provides the neccessary hooks. I urge you to add Ctrl-C as well (it only works when a line is expected, not when a char is being read).
Also, why not compare the input characters with string equality? $c eq "q"
reads nicer.