-
Notifications
You must be signed in to change notification settings - Fork 80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Raw mode bugfix #1
Comments
Thanks, I was aware of this issue but didn't know how to fix it. Setting Unsetting I'm going to have to look into this more to find the proper solution. Or maybe someone who knows this stuff better will come along and help out... |
You're right! I didn't notice that it stopped blocking entirely! It seems that FNDELAY and O_NONBLOCK are basically the same thing just different standards: It's possible that VTIME just doesn't work in this environment? In any case I went with this so I can continue the tutorial: #include <ctype.h>
+#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
struct termios orig_termios;
void disableRawMode() {
tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios);
}
void enableRawMode() {
tcgetattr(STDIN_FILENO, &orig_termios);
atexit(disableRawMode);
+ fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL) | O_NONBLOCK);
struct termios raw = orig_termios;
raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
raw.c_oflag &= ~(OPOST);
raw.c_cflag |= (CS8);
raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
raw.c_cc[VMIN] = 0;
- raw.c_cc[VTIME] = 1;
+ raw.c_cc[VTIME] = 0;
tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
}
int main() {
enableRawMode();
while (1) {
char c = '\0';
read(STDIN_FILENO, &c, 1);
+ if(errno==EAGAIN) {
+ struct timespec ts = {0,100000000};
+ nanosleep(&ts, NULL);
+ }
if (isprint(c)) {
printf("%d ('%c')\r\n", c, c);
} else {
printf("%d\r\n", c);
}
if (c == 'q') {
break;
}
}
return 0;
} |
Okay so I've continued along (I'm not bothering to sleep anymore - but this creates another problem at step 32 - we don't get the answer on STD_OUT immediately so we have to check for EAGAIN and continue without incrementing. This doesn't create an infinite loop in practice because the answer (ending with R) does come eventually. I'm not sure why the answer isn't immediately available - perhaps STDOUT isn't blocking now either? Maybe this explains some other problems that happen in O_NONBLOCK mode? int getCursorPosition(int *rows, int *cols) {
char buf[32];
unsigned int i = 0;
if (write(STDOUT_FILENO, "\x1b[6n", 4) != 4) return -1;
char c;
while (i < sizeof(buf) - 1) {
- if (read(STDIN_FILENO, &buf[i], 1) != 1) break;
+ if (read(STDIN_FILENO, &buf[i], 1) != 1) {
+ if (errno == EAGAIN) continue;
+ break;
+ }
if (buf[i] == 'R') break;
i++;
}
buf[i] = '\0';
printf("\r\n&buf[1]: '%s'\r\n", &buf[1]);
editorReadKey();
return -1;
} |
Hi!
Thanks for the tutorial! It's been handy refresher for my c skills.
Raw mode still blocks for me (Windows 10 / Bash on Ubuntu on Windows) because STDIN is set to block.
I was going to submit a pull request but then the steps.diff isn't really human editable. It's a 1 liner anyway!
The text was updated successfully, but these errors were encountered: