tty device is in canonical mode (the one where the tty line discipline implements a simple line editor) so an
eof character (
^D by default) received from the other end causes
read() to return nothing.
That would be the same as when you run
od -vx --endian=big
in a terminal and type Ctrl-D.
Another explanation would be that the canonical mode is off but the
VMIN termios setting is set to 0. With VMIN = 0, a
read() on the device file returns whatever there is there ready to be read if any straight away and nothing otherwise (meaning end-of-file) (unless VTIME > 0 in which case it waits up to VTIME deciseconds for at least one byte).
Again, you can try it in a terminal with:
s=$(stty -g); stty -icanon min 0 time 0; od -vx --endian=big; stty "$s"
Check the current settings with:
stty -a < /dev/ttyUSB0
/dev/ttyUSB0 is a serial device which is just meant to be used to transfer data and not to be used as a terminal, you should issue a
stty raw -echo < /dev/ttyUSB0
In effect, that disables most of the effects of the tty line discipline on it.
See What are the responsibilities of each Pseudo-Terminal (PTY) component (software, master side, slave side)? and your
stty(1) man pages for more information.