Files
six/sys_select.c
2025-06-10 12:11:08 +02:00

107 lines
2.2 KiB
C

#include <termios.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>
#include "uselect.h"
static int lastFd=-1;
static struct termios atts;
static int echo=1;
void sys_keys_on(void) {
int iret;
struct termios attr;
if (echo) {
iret=tcgetattr(STDIN_FILENO,&attr);
atts=attr; /* save term. attr. */
if (iret!=0) { perror("***\n");}
attr.c_lflag &= ~(ICANON) & ~(ECHO); /* canonical mode off, echo off */
attr.c_cc[VMIN]=0;
attr.c_cc[VTIME]=1; /* 0.1 sec */
iret= tcsetattr(STDIN_FILENO,TCSANOW,&attr);
if (iret!=0) {perror("***\n");}
echo=0;
}
}
void sys_keys_off(void) {
int iret;
if (!echo) {
iret=tcsetattr(STDIN_FILENO,TCSANOW,&atts); /* restore term. attributes */
if (iret!=0) {perror("***\n");};
echo=1;
}
}
static int getChar(void) {
unsigned char c;
int rt;
rt = read(STDIN_FILENO, &c, 1);
if (rt<=0) {
return EOF;
} else {
return c;
}
}
int sys_select_or_key(fd_set *mask, int msecTmo, int *key) {
int fd, iret, fd1, chr;
struct timeval tmo, tmo0={0,0};
fd_set rmask;
sys_keys_on();
rmask=*mask;
iret=uselect(FD_SETSIZE, &rmask, NULL, NULL, &tmo0);
if (iret<0) {
FD_ZERO(&rmask);
perror("error in select");
}
fd1=STDIN_FILENO;
/* chr=fgetc(stdin); */
chr = getChar();
if (chr == EOF && iret==0) { /* */
rmask=*mask;
FD_SET(STDIN_FILENO, &rmask);
if (msecTmo>=0) {
if (msecTmo>100) { /* reduce 100 ms for the 1 tenth second in fgetc */
msecTmo=msecTmo-100;
} else {
msecTmo=1;
}
tmo.tv_sec=msecTmo / 1000;
tmo.tv_usec=(msecTmo%1000)*1000;
iret=uselect(FD_SETSIZE, &rmask, NULL, NULL, &tmo);
} else {
iret=uselect(FD_SETSIZE, &rmask, NULL, NULL, NULL);
}
if (iret<0) {
FD_ZERO(&rmask);
perror("error in select");
}
if (FD_ISSET(STDIN_FILENO, &rmask)) {
chr = getChar();
/* chr=fgetc(stdin); */
}
FD_CLR(STDIN_FILENO, &rmask);
}
if (chr==EOF) {
chr=0;
fd1=-1;
for (fd=1; fd<FD_SETSIZE; fd++) {
if (FD_ISSET(fd, &rmask)) {
if (fd1<0) {
fd1=fd; /* first fd */
} else if (fd>lastFd) {
fd1=fd; break;
}
}
}
}
*mask=rmask;
*key=chr;
return(fd1);
}