tcpdump: Ensure loop monitor termination

Update #4649.
This commit is contained in:
Sebastian Huber 2022-05-11 08:24:07 +02:00
parent 47ec4b85e5
commit 45c9bd23a0

View File

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