39
39
#include < stdarg.h>
40
40
#include < stdio.h>
41
41
42
+ #define MOCK_PORT_SHIFTER 9000
43
+
42
44
bool user_exit = false ;
43
45
const char * host_interface = nullptr ;
44
46
size_t spiffs_kb = 1024 ;
45
47
bool ignore_sigint = false ;
46
48
bool restore_tty = false ;
49
+ bool mockdebug = false ;
50
+ int mock_port_shifter = MOCK_PORT_SHIFTER;
47
51
48
52
#define STDIN STDIN_FILENO
49
53
50
54
static struct termios initial_settings;
51
55
56
+ int mockverbose (const char * fmt, ...)
57
+ {
58
+ va_list ap;
59
+ va_start (ap, fmt);
60
+ if (mockdebug)
61
+ return fprintf (stderr, MOCK) + vfprintf (stderr, fmt, ap);
62
+ return 0 ;
63
+ }
64
+
52
65
static int mock_start_uart (void )
53
66
{
54
67
struct termios settings;
55
68
56
- if (!isatty (STDIN)) return 0 ;
57
- if (tcgetattr (STDIN, &initial_settings) < 0 ) return -1 ;
69
+ if (!isatty (STDIN))
70
+ {
71
+ perror (" setting tty in raw mode: isatty(STDIN)" );
72
+ return -1 ;
73
+ }
74
+ if (tcgetattr (STDIN, &initial_settings) < 0 )
75
+ {
76
+ perror (" setting tty in raw mode: tcgetattr(STDIN)" );
77
+ return -1 ;
78
+ }
58
79
settings = initial_settings;
59
80
settings.c_lflag &= ~(ignore_sigint ? ISIG : 0 );
60
81
settings.c_lflag &= ~(ECHO | ICANON);
61
82
settings.c_iflag &= ~(ICRNL | INLCR | ISTRIP | IXON);
62
83
settings.c_oflag |= (ONLCR);
63
84
settings.c_cc [VMIN] = 0 ;
64
85
settings.c_cc [VTIME] = 0 ;
65
- if (tcsetattr (STDIN, TCSANOW, &settings) < 0 ) return -2 ;
86
+ if (tcsetattr (STDIN, TCSANOW, &settings) < 0 )
87
+ {
88
+ perror (" setting tty in raw mode: tcsetattr(STDIN)" );
89
+ return -1 ;
90
+ }
66
91
restore_tty = true ;
67
92
return 0 ;
68
93
}
@@ -71,11 +96,14 @@ static int mock_stop_uart(void)
71
96
{
72
97
if (!restore_tty) return 0 ;
73
98
if (!isatty (STDIN)) {
74
- perror (" isatty(STDIN)" );
75
- // system("stty sane"); <- same error message "Inappropriate ioctl for device"
76
- return 0 ;
99
+ perror (" restoring tty: isatty(STDIN)" );
100
+ return -1 ;
101
+ }
102
+ if (tcsetattr (STDIN, TCSANOW, &initial_settings) < 0 )
103
+ {
104
+ perror (" restoring tty: tcsetattr(STDIN)" );
105
+ return -1 ;
77
106
}
78
- if (tcsetattr (STDIN, TCSANOW, &initial_settings) < 0 ) return -1 ;
79
107
printf (" \e[?25h" ); // show cursor
80
108
return (0 );
81
109
}
@@ -94,11 +122,14 @@ void help (const char* argv0, int exitcode)
94
122
" -h\n "
95
123
" -i <interface> - use this interface for IP address\n "
96
124
" -l - bind tcp/udp servers to interface only (not 0.0.0.0)\n "
125
+ " -s - port shifter (default: %d, when root: 0)\n "
97
126
" -c - ignore CTRL-C (send it via Serial)\n "
98
127
" -f - no throttle (possibly 100%%CPU)\n "
128
+ " -b - blocking tty/mocked-uart (default: not blocking tty)\n "
99
129
" -S - spiffs size in KBytes (default: %zd)\n "
130
+ " -v - mock verbose\n "
100
131
" (negative value will force mismatched size)\n "
101
- , argv0, spiffs_kb);
132
+ , argv0, MOCK_PORT_SHIFTER, spiffs_kb);
102
133
exit (exitcode);
103
134
}
104
135
@@ -108,8 +139,11 @@ static struct option options[] =
108
139
{ " fast" , no_argument, NULL , ' f' },
109
140
{ " local" , no_argument, NULL , ' l' },
110
141
{ " sigint" , no_argument, NULL , ' c' },
142
+ { " blockinguart" , no_argument, NULL , ' b' },
143
+ { " verbose" , no_argument, NULL , ' v' },
111
144
{ " interface" , required_argument, NULL , ' i' },
112
145
{ " spiffskb" , required_argument, NULL , ' S' },
146
+ { " portshifter" , required_argument, NULL , ' s' },
113
147
};
114
148
115
149
void cleanup ()
@@ -133,13 +167,18 @@ void control_c (int sig)
133
167
134
168
int main (int argc, char * const argv [])
135
169
{
136
- signal (SIGINT, control_c);
137
-
138
170
bool fast = false ;
171
+ bool blocking_uart = false ;
172
+
173
+ signal (SIGINT, control_c);
174
+ if (geteuid () == 0 )
175
+ mock_port_shifter = 0 ;
176
+ else
177
+ mock_port_shifter = MOCK_PORT_SHIFTER;
139
178
140
179
for (;;)
141
180
{
142
- int n = getopt_long (argc, argv, " hlcfi:S :" , options, NULL );
181
+ int n = getopt_long (argc, argv, " hlcfbvi:S:s :" , options, NULL );
143
182
if (n < 0 )
144
183
break ;
145
184
switch (n)
@@ -153,6 +192,9 @@ int main (int argc, char* const argv [])
153
192
case ' l' :
154
193
global_ipv4_netfmt = NO_GLOBAL_BINDING;
155
194
break ;
195
+ case ' s' :
196
+ mock_port_shifter = atoi (optarg );
197
+ break ;
156
198
case ' c' :
157
199
ignore_sigint = true ;
158
200
break ;
@@ -162,12 +204,19 @@ int main (int argc, char* const argv [])
162
204
case ' S' :
163
205
spiffs_kb = atoi (optarg );
164
206
break ;
207
+ case ' b' :
208
+ blocking_uart = true ;
209
+ break ;
210
+ case ' v' :
211
+ mockdebug = true ;
212
+ break ;
165
213
default :
166
- fprintf (stderr, MOCK " bad option '%c'\n " , n);
167
- exit (EXIT_FAILURE);
214
+ help (argv[0 ], EXIT_FAILURE);
168
215
}
169
216
}
170
217
218
+ mockverbose (" server port shifter: %d\n " , mock_port_shifter);
219
+
171
220
if (spiffs_kb)
172
221
{
173
222
String name = argv[0 ];
@@ -180,8 +229,11 @@ int main (int argc, char* const argv [])
180
229
// setup global global_ipv4_netfmt
181
230
wifi_get_ip_info (0 , nullptr );
182
231
183
- // set stdin to non blocking mode
184
- mock_start_uart ();
232
+ if (!blocking_uart)
233
+ {
234
+ // set stdin to non blocking mode
235
+ mock_start_uart ();
236
+ }
185
237
186
238
// install exit handler in case Esp.restart() is called
187
239
atexit (cleanup);
0 commit comments