Getting the ^D(owengage.com)
owengage.com
Getting the ^D
https://owengage.com/writing/2023-04-08-getting-the-ctrl-d/
55 comments
See also the evil interview question, "how does a keyboard type characters into an Emacs buffer?"
You could spend 8 hours describing it from power, to USB descriptors, to debouncing, to keymapping, to matrix scanning, to ptys, to editor string management algorithms to Lisp. And passing by this article as well!
You could spend 8 hours describing it from power, to USB descriptors, to debouncing, to keymapping, to matrix scanning, to ptys, to editor string management algorithms to Lisp. And passing by this article as well!
Do you have a link? I can't find anything under that title.
Nah it's just an interesting interview question if you are looking for a generalist. There's also "what happens when you type into the address bar of your browser and hit return?" Can cover DNS, wifi, BGP, servers, DOM layout, TLS, etc.
I like how he references Linus' TTY Demystified article (a popular repost here on HN too) --- that has almost become a de-facto source of information on the details of how the TTY subsystem works.
The `c_cc` array is configurable via the stty command or the termios(3) API.
To override the character for "EOF," change ^D to something else in the following command and run it:
To override the character for "EOF," change ^D to something else in the following command and run it:
stty eof ^Ddoes the program not simply receive ^D as a normal character? I thought i was up to the program to interpret it
When a program reads from a pseudo-terminal device in "cooked mode"[0], ^D is the default control character to indicate "no more input will be made available."
A program reading from a file handle other than a pseudo-terminal or a pseudo-terminal set to be in "raw mode" will behave as you describe.
0 - https://en.wikipedia.org/wiki/Terminal_mode
A program reading from a file handle other than a pseudo-terminal or a pseudo-terminal set to be in "raw mode" will behave as you describe.
0 - https://en.wikipedia.org/wiki/Terminal_mode
Yes but the expectation still is to interpret it as "end of input", even for interactive programs. One that doesn't (unfortunately) is zsh where ^D makes autosuggest prompt "do you wish to see all n possibilities?"
It does not. Its still up to the program with how it wants to deal with end of file though.
The author takes the long way round and misses the point by a little bit.
ANSI C defines EOF, the 2nd edition by Kernighan and Ritchie page 151 states 'getchar returns the next input character each time it is called, or EOF when it encounters end of file. The symbolic constant EOF is defined in <stdio.h>.
The value is typically -1, bit tests should be written in terms of EOF so as to be independent of the specific value.'
ANSI C defines EOF, the 2nd edition by Kernighan and Ritchie page 151 states 'getchar returns the next input character each time it is called, or EOF when it encounters end of file. The symbolic constant EOF is defined in <stdio.h>.
The value is typically -1, bit tests should be written in terms of EOF so as to be independent of the specific value.'
The discussion is about how terminals and pseudo terminals handle control characters, specifically ^D / EOF / termios.c_cc[VEOF] which is a few layers below getchar(). man stty(1) or termios(5) for more information.
perhaps point out that there is no actual EOF in a file in modern operating systems - i bang on about this here: https://latedev.wordpress.com/2012/12/04/all-about-eof/
EOF is also used to indicate error(s) in a stream.
Its value is platform dependent. As per the C++ standard[0]:
Its value is platform dependent. As per the C++ standard[0]:
It is a macro definition of type int that expands into
a negative integral constant expression (generally, -1).
0 - https://cplusplus.com/reference/cstdio/EOF/please do not use cplusplus.com, use cppreference instead. cplusplus.com often is wrong, out of date, or just missing things.
Noted.
Is this particular citation, "wrong, out of date, or just missing things"?
Is this particular citation, "wrong, out of date, or just missing things"?
None of the above for this case, but generally not a good idea to look there. Instead: https://en.cppreference.com/w/c/io
Very interesting, my naive assumption up to now had honestly been that ^D was just the shortcut for a NULL byte, 0x0 and everything just thus assumed it’d reached the end of the stream and finished up based on that.
Sending a special EOT 0x4 that gets special terminal and kernel handling feels just a little less… elegant… than what I had imagined.
I am curious now, would it be possibly to make a keyboard generate a NULL byte either by existing keyboard shortcut or custom hardware - and how the system would handle it? My guess would be that keyboards sending NULL might not be possible over keyboard protocol at all but I genuinely have no idea.
Sending a special EOT 0x4 that gets special terminal and kernel handling feels just a little less… elegant… than what I had imagined.
I am curious now, would it be possibly to make a keyboard generate a NULL byte either by existing keyboard shortcut or custom hardware - and how the system would handle it? My guess would be that keyboards sending NULL might not be possible over keyboard protocol at all but I genuinely have no idea.
Please look at ascii table to see why ctrl-{key} sends a corresponding control code and why the modifier is called “control”: https://www.commfront.com/pages/ascii-chart
The article explained it well enough. Makes sense, I just was unaware. From that chart though then could ^` generate a NULL byte?
The chart also lists the control key combination for each control byte, for NUL, it's C-@.
^` works too.
"I am curious now, would it be possible to make the keyboard generate a NULL byte either by existing keyboard shortcut or custom hardware - and how would the system handle it?"
Not sure I understand the point of the experiment, but in NetBSD kernel one can remap the keyboard, e.g., set a key to 0x00. How to do this in Linux kernel is a question for reader.
https://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/sys/dev...
Not sure I understand the point of the experiment, but in NetBSD kernel one can remap the keyboard, e.g., set a key to 0x00. How to do this in Linux kernel is a question for reader.
https://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/sys/dev...
The NUL byte has no special meaning in file I/O, or the terminal. (Historically, the only special meaning was as a no-op character that does nothing.) The convention of using NUL as a termination character only exists for in-memory strings in C, and has no connection to file I/O.
If EOF was a character, you couldn't process (binary) streams that contain the character.
^@ produces the NUL character.
^@ produces the NUL character.
It's not a good example, because bash disables the canonical mode. When you type ^D this happens:
(And then bash ignores the read EOT character.)