I came across this code which was supposed to create an alternative POSIX function (new_kbhit()
) for a DOS function kbhit()
.
// Standard C headers
#include <stdio.h>
#include <stdbool.h>
// POSIX system headers
#include <sys/select.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <stropts.h>
/////////////////////////////////////////////////////////////
// FUNCTION: kbhit_new()
//
// It returns 0. But if a key is pressed it returns number
// of pending bytes.
/////////////////////////////////////////////////////////////
int new_kbhit() {
// Stdin's file descriptor (fd) is always 0, stdout's is 1 and stderr's is 2.
static const int stdin_fd = 0;
// This is static because we only want to disable buffering when this function is 1st called.
static bool initialized = false;
// Define the terminal structure named term.
struct termios term;
// Define an integer that will store the number of pending bytes.
int bytes_waiting;
if (! initialized) {
// Get parameter STDIN of the terminal and store it inside termios structure (term).
tcgetattr(stdin_fd, &term);
// A: Remove termios structure's (term) flag ICANON inside the local modes i.e. c_lflag.
// B: Removing flag ICANON will dissable canonnical processing.
// C: When there is no canonical processing
term.c_lflag &= ~ICANON;
// Set terminal's attributes immediately (TCSANOW). Attributes are applied from termios (term).
tcsetattr(stdin_fd, TCSANOW, &term);
// Assign a buffer NULL to stream stdin. This disables buffering on stdin so pressed key is shown.
setbuf(stdin, NULL);
initialized = true;
}
// A: ioctl operates on the "streams devices" but it needs it's file descriptors (fd)..
// B: Linux is not 100% POSIX compliant. It supports more than POSIX defines.
// C: Linux supports "streams device" FIONREAD (https://www.kernel.org/doc/html/latest/)
// C: FIONREAD device stores an integer i.e. "pending number of bytes" in last argument of ioctl.
ioctl(stdin_fd, FIONREAD, &bytes_waiting);
return bytes_waiting;
}
/////////////////////////////////////////////////////////////
// EXAMPLE:
/////////////////////////////////////////////////////////////
#include <unistd.h>
int main(int argc, char** argv) {
printf("Press any key to terminate:
");
while (! new_kbhit()) {
putchar('.');
fflush(stdout);
usleep(1000000);
}
printf("
Done.
");
return 0;
}
Using POSIX standard I somehow deciphered what this code does (comments). But to me it does exactly the same if I comment out almost everything inside the function new_kbdhit()
which then looks like this:
int new_kbhit() {
int bytes_waiting;
ioctl(stdin_fd, FIONREAD, &bytes_waiting);
return bytes_waiting;
}
So I can't confirm that this code does anything at all. How could I test it to see it's true potential? I have hard time understanding it's value at all.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…