Everyone knows what ^D does on Unix; it generates an end of file, so that cat or various other programs will exit (especially if they have accidentally wound up reading from standard input).

But this is just the usual effects of typing ^D; it is not what it actually does. What ^D actually does is simple but subtle:

Typing ^D causes the tty driver to immediately finish a read() .

Normally doing a read() from a terminal is line-buffered inside the tty driver; your program only wakes up when the tty driver sees the newline, at which point you get back the full line. (Note that this buffering is distinct from anything that your language's IO system may be doing.)

Typing ^D causes the tty driver to stop waiting for a newline and immediately return from the read() with however much of the line has been accumulated to date. If you haven't typed anything on the line yet, there is nothing accumulated and the read() will return 0 bytes, which is conveniently the signal for end of file. If you have typed something the program will get it; because it doesn't have a trailing newline, the program's own line-buffering may take over and keep read() ing to get the rest of the line.

(Other programs will immediately process the partial line with no buffering; cat is one example of this.)

Once you've typed ^D on a partial line, that portion of the line is immutable because it's already been given to the program. Most Unixes won't let you backspace over such partial lines; effectively they become output, not input.

(Note that modern shells are not good examples of this, because they don't do line-buffered input; to support command line editing, they switch terminal input into an uninterpreted mode. So they get the raw ^D and can do whatever they want with it, and they can let you edit as much of the pending line as they want.)