forked from bartprescott/vbus-collector
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathkbhit.c
120 lines (96 loc) · 3.2 KB
/
kbhit.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//****************************************************************************
// kbhit.c
//
// (c) Hewell Technology Ltd. 2014
//
//****************************************************************************
#include <stdio.h>
#include <signal.h>
#include <termios.h>
#include <stdlib.h>
#include <unistd.h>
#include "kbhit.h"
struct termios oldtermios;
void (*usr1Callback)();
int ttyraw(int fd)
{
/* Set terminal mode as follows:
Noncanonical mode - turn off ICANON.
Turn off signal-generation (ISIG)
including BREAK character (BRKINT).
Turn off any possible preprocessing of input (IEXTEN).
Turn ECHO mode off.
Disable CR-to-NL mapping on input.
Disable input parity detection (INPCK).
Disable stripping of eighth bit on input (ISTRIP).
Disable flow control (IXON).
Use eight bit characters (CS8).
Disable parity checking (PARENB).
Disable any implementation-dependent output processing (OPOST).
One byte at a time input (MIN=1, TIME=0).
*/
struct termios newtermios;
if(tcgetattr(fd, &oldtermios) < 0)
{
return(-1);
}
newtermios = oldtermios;
newtermios.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
/* OK, why IEXTEN? If IEXTEN is on, the DISCARD character
is recognized and is not passed to the process. This
character causes output to be suspended until another
DISCARD is received. The DSUSP character for job control,
the LNEXT character that removes any special meaning of
the following character, the REPRINT character, and some
others are also in this category.
*/
newtermios.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
/* If an input character arrives with the wrong parity, then INPCK
is checked. If this flag is set, then IGNPAR is checked
to see if input bytes with parity errors should be ignored.
If it shouldn't be ignored, then PARMRK determines what
character sequence the process will actually see.
When we turn off IXON, the start and stop characters can be read.
*/
newtermios.c_cflag &= ~(CSIZE | PARENB);
/* CSIZE is a mask that determines the number of bits per byte.
PARENB enables parity checking on input and parity generation
on output.
*/
newtermios.c_cflag |= CS8;
/* Set 8 bits per character. */
newtermios.c_oflag &= ~(OPOST);
/* This includes things like expanding tabs to spaces. */
newtermios.c_cc[VMIN] = 1;
newtermios.c_cc[VTIME] = 0;
/* You tell me why TCSAFLUSH. */
if(tcsetattr(fd, TCSAFLUSH, &newtermios) < 0)
{
return(-1);
}
return(0);
}
int ttyreset(int fd)
{
if(tcsetattr(fd, TCSAFLUSH, &oldtermios) < 0)
return(-1);
return(0);
}
void sigcatch(int sig)
{
if (sig == SIGUSR1)
{
usr1Callback();
}
else
{
ttyreset(0);
exit(0);
}
}
int caughtSigQuit(void (*userSignalCallback)())
{
usr1Callback = *userSignalCallback;
signal(SIGUSR1, sigcatch);
return ((size_t)signal(SIGQUIT, sigcatch) < 0);
}