-
Notifications
You must be signed in to change notification settings - Fork 6
/
char-pty.c
130 lines (98 loc) · 2.07 KB
/
char-pty.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
126
127
128
129
130
//-------------------------------------------------------------------------------
// EMU86 - PTY character backend
//-------------------------------------------------------------------------------
#define _DEFAULT_SOURCE // for cfmakeraw() on Linux
#define _DARWIN_C_SOURCE // for cfmakeraw() on MacOS
#define _XOPEN_SOURCE 600 // for posix_openpt() & ptsname()
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include "emu-char.h"
static int _ptm = -1;
int char_send (byte_t c)
{
int err = 0;
if (_ptm >= 0)
{
int n = write (_ptm, &c, 1);
if (n != 1)
{
perror ("warning: cannot write to PTM:");
err = -1;
}
}
return err;
}
int char_recv (byte_t * c)
{
int err = 0;
if (_ptm >= 0)
{
int n = read (_ptm, c, 1);
if (n != 1)
{
perror ("warning: cannot read from PTM:");
err = -1;
}
}
return err;
}
int char_poll ()
{
fd_set fdsr;
FD_ZERO (&fdsr);
FD_SET (_ptm, &fdsr);
struct timeval tv = { 0L, 0L }; // immediate
int s = select (_ptm + 1, &fdsr, NULL, NULL, &tv);
if (s < 0) return -1;
if (FD_ISSET (_ptm, &fdsr)) return 1; // has char
return 0; // no char
}
void char_raw ()
{
}
void char_normal ()
{
}
int char_init ()
{
while (1)
{
// Create pseudo terminal for serial emulation
_ptm = posix_openpt (O_RDWR);
if (_ptm < 0)
{
perror ("warning: cannot create PTM:");
break;
}
// The following functions return -1 on success !?!
grantpt (_ptm);
unlockpt (_ptm);
// Set slave in raw mode (avoid echo and other cooking)
struct termios tios;
tcgetattr (_ptm, &tios);
cfmakeraw (&tios);
tcsetattr (_ptm, TCSANOW, &tios);
char * path = ptsname (_ptm);
printf ("info: PTS for serial emulation: %s\n", path);
int f = open ("emu86.pts", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
write (f, path, strlen (path));
close (f);
break;
}
return 0;
}
void char_term ()
{
unlink ("emu86.pts");
// Close pseudo terminal
if (_ptm >= 0)
{
close (_ptm);
_ptm = -1;
}
}