Skip to content

Commit 906968b

Browse files
committed
Merge branch 'simulator'
2 parents e74e3b8 + 4b8838a commit 906968b

File tree

2 files changed

+57
-10
lines changed

2 files changed

+57
-10
lines changed

test/simulator/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Simulator
2+
3+
## Signals
4+
5+
The simulator can be forcefully shutdown with SIGTERM. It can also be told to
6+
disconnect from the client using SIGHUP.

test/simulator/simulator.c

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ static const char* _simulator_version = "1.0.0";
4242
int data_len;
4343
int commfd;
4444

45-
static volatile sig_atomic_t sigint_called = false;
45+
static volatile sig_atomic_t quitting = false;
46+
static volatile sig_atomic_t hangup = false;
4647
static int sockfd;
4748

4849
static int get_usb_message_socket(uint8_t* input)
@@ -71,17 +72,28 @@ static void simulate_firmware_execution(const uint8_t* input)
7172
usb_processing_process(usb_processing_hww());
7273
}
7374

74-
static void _int_handler(int signum)
75+
static void _quit_handler(int signum)
7576
{
7677
(void)signum;
77-
sigint_called = true;
78-
close(sockfd);
78+
quitting = true;
79+
}
80+
81+
static void _hup_handler(int signum)
82+
{
83+
(void)signum;
84+
hangup = true;
7985
}
8086

8187
int main(int argc, char* argv[])
8288
{
83-
signal(SIGINT, _int_handler);
84-
// Default port number
89+
struct sigaction psa;
90+
memset(&psa, 0, sizeof(struct sigaction));
91+
psa.sa_handler = _quit_handler;
92+
sigaction(SIGINT, &psa, NULL);
93+
sigaction(SIGTERM, &psa, NULL);
94+
psa.sa_handler = _hup_handler;
95+
sigaction(SIGHUP, &psa, NULL);
96+
// Default port number
8597
int portno = 15423;
8698

8799
struct option long_options[] = {
@@ -162,11 +174,12 @@ int main(int argc, char* argv[])
162174
while (1) {
163175
if ((commfd = accept(sockfd, (struct sockaddr*)&serv_addr, (socklen_t*)&serv_addr_len)) <
164176
0) {
165-
if (sigint_called) {
166-
printf("\nGot Ctrl-C, exiting\n");
177+
if (quitting) {
178+
printf("\nGot signal, exiting\n");
179+
break;
167180
}
168181
perror("accept");
169-
return 1;
182+
break;
170183
}
171184
printf("Socket connection setup success\n");
172185

@@ -175,7 +188,33 @@ int main(int argc, char* argv[])
175188
int temp_len;
176189
while (1) {
177190
// Simulator polls for USB messages from client and then processes them
178-
if (!get_usb_message_socket(input)) break;
191+
if (get_usb_message_socket(input) < 1) {
192+
if (quitting) {
193+
printf("\nGot term/int signal, exiting\n");
194+
// Using LINGER we force a TCP RST instead of graceful shutdown. Without this
195+
// trick the port keeps being bound for 10s of seconds after the application has
196+
// died, hindering future executions.
197+
struct linger sol = {.l_onoff = 1, .l_linger = 0};
198+
int res = setsockopt(commfd, SOL_SOCKET, SO_LINGER, &sol, sizeof(sol));
199+
if (res) {
200+
perror("setsockopt");
201+
}
202+
shutdown(commfd, SHUT_RDWR);
203+
uint8_t buf[1024];
204+
while (read(commfd, buf, sizeof(buf)) > 0);
205+
close(commfd);
206+
goto after_main_loop;
207+
}
208+
if (hangup) {
209+
hangup = false;
210+
printf("\nGot hangup signal, disconnecting\n");
211+
shutdown(commfd, SHUT_RDWR);
212+
uint8_t buf[1024];
213+
while (read(commfd, buf, sizeof(buf)) > 0);
214+
close(commfd);
215+
}
216+
break;
217+
}
179218
simulate_firmware_execution(input);
180219

181220
// If the USB message to be sent from firmware is bigger than one packet,
@@ -196,5 +235,7 @@ int main(int argc, char* argv[])
196235
printf("Socket connection closed\n");
197236
printf("Waiting for new clients, CTRL+C to shut down the simulator\n");
198237
}
238+
after_main_loop:
239+
close(sockfd);
199240
return 0;
200241
}

0 commit comments

Comments
 (0)