forked from mfld-fr/emu86
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchar-stdio.c
125 lines (97 loc) · 2 KB
/
char-stdio.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
121
122
123
124
125
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <signal.h>
#include <sys/ioctl.h>
#include "emu-char.h"
static struct termios def_termios;
int char_send (byte_t c)
{
int err = 0;
int n = write (1, &c, 1);
if (n != 1)
{
perror ("warning: cannot write to stdio");
err = -1;
}
return err;
}
int char_recv (byte_t * c)
{
int err = 0;
if (!char_poll())
{
fd_set fdsr;
FD_ZERO (&fdsr);
FD_SET (0, &fdsr);
int s = select (1, &fdsr, NULL, NULL, NULL);
if (s < 0)
return -1; // required for updated source when ^C hit on read
}
int n = read (0, c, 1);
if (n == 0) return 0;
if (n != 1)
{
perror ("warning: cannot read from console");
err = -1;
}
if (*c == 0x7f) *c = '\b'; // convert DEL to BS
return err;
}
int char_poll ()
{
fd_set fdsr;
FD_ZERO (&fdsr);
FD_SET (0, &fdsr);
struct timeval tv = { 0L, 0L }; // immediate
int s = select (1, &fdsr, NULL, NULL, &tv);
if (s < 0) return -1;
if (FD_ISSET (0, &fdsr)) return 1; // has char
return 0; // no char
}
void char_raw ()
{
struct termios termios;
fflush(stdout);
tcgetattr(0, &termios);
termios.c_iflag &= ~(ICRNL|IGNCR|INLCR);
termios.c_lflag &= ~(ECHO|ECHOE|ECHONL|ICANON);
termios.c_lflag |= ISIG;
tcsetattr(0, TCSADRAIN, &termios);
int nonblock = 1;
ioctl(0, FIONBIO, &nonblock);
}
void char_normal ()
{
int nonblock = 0;
fflush(stdout);
ioctl(0, FIONBIO, &nonblock);
tcsetattr(0, TCSADRAIN, &def_termios);
}
// Keep this signal catching until all the assert() are removed
// to avoid leaving the EMU86 terminal in raw mode after abort
// See GitHub issue #15
static void catch_abort(int sig)
{
char_term();
exit(1);
}
int char_init ()
{
#ifdef __APPLE__
static char buf[1];
setvbuf(stdout, buf, _IOFBF, sizeof(buf));
#endif
tcgetattr(0, &def_termios);
char_raw();
signal(SIGABRT, catch_abort);
return 0;
}
void char_term ()
{
if (def_termios.c_oflag) char_normal();
}