blob: 5c99b7f70bddf3042e7a3bd3cbad902292f8b126 (
plain)
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
|
/*
* most of this stuff is ripped from solar's excelent john-1.6 source
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <termios.h>
static int tty_fd = 0;
static int tty_buf = -1;
static struct termios saved_ti;
/*
* Reads a character, returns -1 if no data available or on error.
*/
int
tty_getchar ()
{
int c;
/*
* process buffer first
*/
if (tty_buf != -1)
{
c = tty_buf;
tty_buf = -1;
return (c);
}
if (tty_fd)
{
c = 0;
if (read (tty_fd, &c, 1) > 0)
return c;
}
return (-1);
}
/*
* check if someone pressed a key
* Actually we do a read on the fd and store the result in a buffer
* todo: check with ioctl if data is pending
* return 1 is data is pending, 0 if not
*/
int
tty_ischar ()
{
if (tty_buf != -1)
return (1);
if ((tty_buf = tty_getchar ()) != -1)
return (1);
return (0);
}
/*
* Restores the terminal parameters and closes the file descriptor.
*/
void
tty_done ()
{
int fd;
if (!tty_fd)
return;
fd = tty_fd;
tty_fd = 0;
tcsetattr (fd, TCSANOW, &saved_ti);
close (fd);
}
/*
* Initializes the terminal for unbuffered non-blocking input. Also registers
* tty_done() via atexit().
*/
void
tty_init ()
{
int fd;
struct termios ti;
if (tty_fd)
return;
if ((fd = open ("/dev/tty", O_RDONLY | O_NONBLOCK)) < 0)
return;
if (tcgetpgrp (fd) != getpid ())
{
close (fd);
return;
}
tcgetattr (fd, &ti);
saved_ti = ti;
ti.c_lflag &= ~(ICANON | ECHO);
ti.c_cc[VINTR] = 3; /* CTRL-C is INTR */
ti.c_cc[VMIN] = 1;
ti.c_cc[VTIME] = 0;
tcsetattr (fd, TCSANOW, &ti);
tty_fd = fd;
atexit (tty_done);
}
|