How can I send CR (i.e. ascii 13) to a c program from keyboard (running linux)? ALSO, why do I have to send EOF twice to terminate this program?

Solution 1:

So, is there actually a way to send a CR from a keyboard under Linux

You are sending a CR, but the tty layer will translate it to a LF by default, so the program cannot receive a CR. Use tcsetattr() to disable the ICRNL mode if you want to avoid this. (But don't forget to save the old settings first, and reset them on exit.)

Search also for raw/cooked/cbreak modes.

and why does the EOF need to be sent twice?

There is actually no such thing as an EOF result at OS level – instead, whenever the read() system call returns 0 bytes, then libc functions report it as an EOF.

So Ctrl+D actually just tells the OS to immediately finish the read() call (that is, without waiting for a newline), and it only becomes an EOF indicator if it causes that read() call to return no data at all. That only happens if you press it immediately after a newline or after a previous Ctrl+D.

You'll see this happening in other programs too. Run strace -e read cat or strace -e read ./myprogram to see it happening in more detail.