I have searched:
and still failed to find the answer that will explain how read(2) knows that is has to block or not block. Yes, read(2) is not the fuction containing the answer, but it is the starting point.
Here I will draw the timeline of the problem:
Where does read(2) check the termios struct to determine that it should read STDIN in an (un)blocking fashion?
In the Linux kernel in TTY implementation. Related documentation https://docs.kernel.org/driver-api/tty/index.html .
First we need the macros from https://elixir.bootlin.com/linux/latest/source/include/linux/tty.h#L40 :
#define TIME_CHAR(tty) ((tty)->termios.c_cc[VTIME])
#define MIN_CHAR(tty) ((tty)->termios.c_cc[VMIN])
Looks like VMIN and VTIME is used around here https://elixir.bootlin.com/linux/latest/source/drivers/tty/n_tty.c#L2212 :
static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, u8 *kbuf,
size_t nr, void **cookie, unsigned long offset)
{
.......
minimum = time = 0;
timeout = MAX_SCHEDULE_TIMEOUT;
if (!ldata->icanon) {
minimum = MIN_CHAR(tty);
if (minimum) {
time = (HZ / 10) * TIME_CHAR(tty);
} else {
timeout = (HZ / 10) * TIME_CHAR(tty);
minimum = 1;
}
}
......
timeout = wait_woken(&wait, TASK_INTERRUPTIBLE,
timeout);
......
if (kb - kbuf >= minimum)
break;
if (time)
timeout = time;