#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
struct termios original_termios;
void set_nonblocking_terminal() {
struct termios ttystate;
tcgetattr(STDIN_FILENO, &original_termios); // Store original terminal attributes
tcgetattr(STDIN_FILENO, &ttystate);
ttystate.c_lflag &= ~(ICANON | ECHO); // turn off canonical mode and echo
ttystate.c_cc[VMIN] = 0;
tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
}
void restore_terminal() {
tcsetattr(STDIN_FILENO, TCSANOW, &original_termios);
}
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("Usage: %s <seconds>\n", argv[0]);
return 1;
}
int seconds = atoi(argv[1]);
set_nonblocking_terminal();
atexit(restore_terminal);
for (int i = seconds; i > 0; i--) {
printf("\rWaiting for %d seconds, press a key to continue ... ", i);
fflush(stdout);
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(STDIN_FILENO, &rfds);
int retval = select(STDIN_FILENO + 1, &rfds, NULL, NULL, &tv);
if (retval == -1) {
perror("select()");
return 1;
} else if (retval) {
if (FD_ISSET(STDIN_FILENO, &rfds)) {
while (getchar() != EOF);
printf("\n");
return 0;
}
}
}
printf("\n");
return 0;
}
compile with
gcc timeout.c -o timeout