Last active
November 27, 2020 19:37
-
-
Save osa1/aede6d2d80b5c2992294ef9522ab03a5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// clang -Wall main.c -o main -DNONBLOCK | |
#include <errno.h> | |
#include <fcntl.h> | |
#include <poll.h> | |
#include <stdbool.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <termios.h> | |
#include <unistd.h> | |
void main_loop(); | |
bool read_until_empty(); | |
int main() | |
{ | |
#if defined(NONBLOCK) | |
int old_stdin_flags = fcntl(STDIN_FILENO, F_GETFL); | |
fcntl(STDIN_FILENO, F_SETFL, old_stdin_flags | O_NONBLOCK); | |
printf("Enabled non-blocking mode\n"); | |
#endif | |
bool fail = false; | |
int tty = open("/dev/tty", O_RDWR); | |
if (tty == -1) { | |
printf("Unable to open /dev/tty\n"); | |
fail = true; | |
goto cleanup; | |
} | |
struct termios old_termios; | |
if (tcgetattr(STDIN_FILENO, &old_termios) == -1) { | |
printf("tcgetattr failed\n"); | |
fail = true; | |
goto cleanup; | |
} | |
struct termios new_termios = old_termios; | |
cfmakeraw(&new_termios); | |
// These really need to be after cfmakeraw() !!!! | |
new_termios.c_cc[VMIN] = 0; | |
new_termios.c_cc[VTIME] = 0; | |
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &new_termios) == -1) { | |
printf("tcsetattr failed\n"); | |
fail = true; | |
goto cleanup; | |
} | |
printf("Type 'q' to quit.\n"); | |
main_loop(); | |
cleanup: | |
tcsetattr(STDIN_FILENO, TCSAFLUSH, &old_termios); | |
#if defined(NONBLOCK) | |
fcntl(STDIN_FILENO, F_SETFL, old_stdin_flags); | |
printf("Restored stdin flags\n"); | |
#endif | |
if (fail) { | |
return 1; | |
} | |
} | |
void main_loop() | |
{ | |
printf("main_loop\n"); | |
struct pollfd fds[1] = { { .fd = STDIN_FILENO, .events = POLLIN } }; | |
for (;;) | |
{ | |
printf("Calling poll()...\n"); | |
int poll_ret = poll(fds, 1, -1); | |
if (poll_ret > 0) | |
{ | |
printf("stdin ready for reading\n"); | |
if (read_until_empty()) | |
{ | |
return; | |
} | |
} | |
} | |
} | |
bool read_until_empty() | |
{ | |
uint8_t buf[10000]; | |
for (;;) | |
{ | |
printf("Calling read()...\n"); | |
ssize_t n_read = read(STDIN_FILENO, buf, 10000); | |
if (n_read == -1) | |
{ | |
if (errno == EAGAIN || errno == EWOULDBLOCK) | |
{ | |
printf("EAGAIN or EWOULDBLOCK\n"); | |
return false; | |
} | |
else | |
{ | |
printf("Error %d: %s\n", errno, strerror(errno)); | |
return false; | |
} | |
} | |
else if (n_read == 0) | |
{ | |
printf("stdin is empty\n"); | |
return false; | |
} | |
else | |
{ | |
printf("Read %zd bytes\n", n_read); | |
if (buf[0] == 3 || buf[0] == 113) | |
{ | |
return true; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment