Thanks, Stefan. Is something like this what should be done then:
(let* ((ch (read-char "cs:")))
(insert (decode-coding-string (char-to-string ch)
(keyboard-coding-system))))
This also has its share of problems since keyboard-coding-system may be
multibyte, in which case you might need to read more than 1 char ;-)
(insert (aref (read-key-sequence) 0))
is another approch which will correctly solve those problems, but will
suffer from yet others: typically after hitting things like C-c or C-x Emacs
will just sit still, waiting for more input before processing it.
You can get closer with
(insert (let ((overriding-terminal-local-map (make-sparse-keymap)))
(aref (read-key-sequence) 0)))
but C-x will still hang because of the C-x 8 prefix in key-translation-map,
and similarly for ESC because of the bindings in function-key-map.