I am trying to implement a terminal emulator in C + SDL2 with a PTY, and this is how it has to be implemented:
fd_set readable;
int maxfd = pty->master;
for (;;) {
FD_ZERO(&readable); //clear fd_set 'readable'
FD_SET(pty->master, &readable); //add 'pty' fd to 'readable'
//here I would theoretically want to add a fd of SDL key input.
//waits until any file descriptor from 'readable' can be read
if (select(maxfd + 1, &readable, NULL, NULL, NULL) == -1) {
//error
}
if (FD_ISSET(pty->master, &readable)) { //if 'pty' is readable
//handle PTY input (A.K.A terminal output)
}
}
However, I want it to include key input from SDL2, to then feed through the PTY.
So how could I collect key input while select()
is running?
I would set the timeout parameter to a relatively small value (perhaps a few milliseconds), then you can loop calling select()
and SDL_PollEvent()
until one or the other returns a keypress.
1 Like
Thank you, that worked!
This is what I have in my program now:
fd_set readable;
int maxfd = pty->master;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
//select will not wait at all
for (;;) {
FD_ZERO(&readable); //clear fd_set 'readable'
FD_SET(pty->master, &readable); //add 'pty' fd to 'readable'
SDL_Event event;
if (SDL_PollEvent(event) {
//detect keypress here
}
//waits until any file descriptor from 'readable' can be read
int select_val = select(maxfd + 1, &readable, NULL, NULL, &tv);
if (select_val == -1) {
//error
} else if (select_val > 0) {
//read character here
}
}
Do be careful that if you set the timeout to zero your program may loop using 100% CPU time until a key is pressed; you definitely don’t want that!
1 Like
Good idea, thanks!
I set the tv.tv_usec
variable to 10000
, and it works the same.