[PATCH 7/8] tcpdump: Ensure loop monitor termination

Sebastian Huber sebastian.huber at embedded-brains.de
Wed May 11 06:56:40 UTC 2022


Update #4650.
---
 freebsd/contrib/tcpdump/tcpdump.c | 44 ++++++++++++++++++++-----------
 1 file changed, 29 insertions(+), 15 deletions(-)

diff --git a/freebsd/contrib/tcpdump/tcpdump.c b/freebsd/contrib/tcpdump/tcpdump.c
index db5c9221..73e2e844 100644
--- a/freebsd/contrib/tcpdump/tcpdump.c
+++ b/freebsd/contrib/tcpdump/tcpdump.c
@@ -1197,26 +1197,22 @@ typedef struct {
 	FILE *in;
 	pcap_t *pd;
 	rtems_id master;
+	bool terminate;
 } pcap_loop_context;
 
 static void
 pcap_loop_monitor(rtems_task_argument arg)
 {
-	pcap_loop_context *ctx;
+	const pcap_loop_context *ctx;
 	FILE *in;
 	pcap_t *pd;
-	rtems_id master;
 	rtems_status_code sc;
 
-	ctx = (pcap_loop_context *)arg;
+	ctx = (const pcap_loop_context *)arg;
 	in = ctx->in;
 	pd = ctx->pd;
-	master = ctx->master;
-
-	sc = rtems_event_transient_send(master);
-	assert(sc == RTEMS_SUCCESSFUL);
 
-	while (true) {
+	while (!ctx->terminate) {
 		int c;
 
 		c = fgetc(in);
@@ -1229,16 +1225,18 @@ pcap_loop_monitor(rtems_task_argument arg)
 		sched_yield();
 	}
 
+	sc = rtems_event_transient_send(ctx->master);
+	assert(sc == RTEMS_SUCCESSFUL);
+
 	rtems_task_exit();
 }
 
 static void
-pcap_create_loop_monitor(pcap_t *pd)
+pcap_create_loop_monitor(pcap_loop_context *ctx, pcap_t *pd)
 {
 	rtems_status_code sc;
 	rtems_task_priority priority;
 	rtems_id id;
-	pcap_loop_context ctx;
 
 	sc = rtems_task_set_priority(RTEMS_SELF, RTEMS_CURRENT_PRIORITY,
 	    &priority);
@@ -1254,12 +1252,21 @@ pcap_create_loop_monitor(pcap_t *pd)
 
 	fprintf(stdout, "tcpdump: press <ENTER> or 'q' or 'Q' to quit\n");
 
-	ctx.in = stdin;
-	ctx.pd = pd;
-	ctx.master = rtems_task_self();
+	ctx->in = stdin;
+	ctx->pd = pd;
+	ctx->master = rtems_task_self();
+	ctx->terminate = false;
 	sc = rtems_task_start(id, pcap_loop_monitor,
-	    (rtems_task_argument)&ctx);
+	    (rtems_task_argument)ctx);
 	assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void
+pcap_terminate_loop_monitor(pcap_loop_context *ctx)
+{
+	rtems_status_code sc;
+
+	ctx->terminate = true;
 
 	sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
 	assert(sc == RTEMS_SUCCESSFUL);
@@ -2207,11 +2214,18 @@ main(int argc, char **argv)
 
 	do {
 #ifdef __rtems__
+		pcap_loop_context ctx;
+
 		if (RFileName == NULL) {
-			pcap_create_loop_monitor(pd);
+			pcap_create_loop_monitor(&ctx, pd);
 		}
 #endif /* __rtems__ */
 		status = pcap_loop(pd, cnt, callback, pcap_userdata);
+#ifdef __rtems__
+		if (RFileName == NULL) {
+			pcap_terminate_loop_monitor(&ctx);
+		}
+#endif /* __rtems__ */
 		if (WFileName == NULL) {
 			/*
 			 * We're printing packets.  Flush the printed output,
-- 
2.35.3



More information about the devel mailing list