[rtems-libbsd commit] tcpdump: Allow enter/return to exit tcpdump.

Chris Johns chrisj at rtems.org
Fri Jun 26 05:17:22 UTC 2015


Module:    rtems-libbsd
Branch:    master
Commit:    9ee52687862e26bed27da0312e2b732345de2602
Changeset: http://git.rtems.org/rtems-libbsd/commit/?id=9ee52687862e26bed27da0312e2b732345de2602

Author:    Chris Johns <chrisj at rtems.org>
Date:      Fri Jun 26 15:15:57 2015 +1000

tcpdump: Allow enter/return to exit tcpdump.

Implement the PCAP loop in a separate thread and block the shell
thread in the stdin getchar. When a user presses enter/return
call the PCAP break loop function to have it return.

---

 freebsd/contrib/tcpdump/tcpdump.c | 105 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 105 insertions(+)

diff --git a/freebsd/contrib/tcpdump/tcpdump.c b/freebsd/contrib/tcpdump/tcpdump.c
index 39be032..3e55b3d 100644
--- a/freebsd/contrib/tcpdump/tcpdump.c
+++ b/freebsd/contrib/tcpdump/tcpdump.c
@@ -45,6 +45,7 @@ static const char rcsid[] _U_ =
 #define setpriority(a, b, c)
 #include <machine/rtems-bsd-program.h>
 #include <machine/rtems-bsd-commands.h>
+#include <rtems.h>
 #endif /* __rtems__ */
 
 /*
@@ -111,6 +112,110 @@ extern int SIZE_BUF;
 #define SIGNAL_REQ_INFO SIGUSR1
 #endif
 
+#ifdef __rtems__
+/*
+ * Run the PCAP loop in a separate task and have the shell thread block on the
+ * input.
+ */
+typedef struct
+{
+    volatile bool running;
+    pcap_t *pd;
+    int cnt;
+    pcap_handler cb;
+    u_char *ud;
+    int ret;
+} rtems_pcap_loop_args;
+
+static void
+rtems_pcap_loop_thread (rtems_task_argument arg)
+{
+    rtems_pcap_loop_args* pcap_loop_arg = (rtems_pcap_loop_args*) arg;
+
+    pcap_loop_arg->ret = pcap_loop(pcap_loop_arg->pd,
+                                   pcap_loop_arg->cnt,
+                                   pcap_loop_arg->cb,
+                                   pcap_loop_arg->ud);
+
+    pcap_loop_arg->running = false;
+
+    rtems_task_delete(RTEMS_SELF);
+}
+
+static int
+rtems_pcap_loop(pcap_t *pd, int cnt, pcap_handler cb, u_char *ud)
+{
+    rtems_status_code   sc;
+    rtems_task_priority priority;
+    rtems_name          name;
+    rtems_id            id;
+
+    rtems_pcap_loop_args pcap_loop_args;
+
+    pcap_loop_args.running = true;
+    pcap_loop_args.pd = pd;
+    pcap_loop_args.cnt = cnt;
+    pcap_loop_args.cb = cb;
+    pcap_loop_args.ud = ud;
+    pcap_loop_args.ret = 0;
+
+    sc = rtems_task_set_priority (RTEMS_SELF, RTEMS_CURRENT_PRIORITY, &priority);
+
+    if (sc != RTEMS_SUCCESSFUL) {
+        fprintf(stderr, "error: cannot get current priority: %s\n",
+                rtems_status_text (sc));
+        return -1;
+    }
+
+    name = rtems_build_name('T', 'C', 'P', 'D');
+
+    sc = rtems_task_create (name, priority, 4 * 1024,
+                            RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
+                            RTEMS_PREEMPT | RTEMS_TIMESLICE | RTEMS_NO_ASR,
+                            &id);
+
+    if (sc != RTEMS_SUCCESSFUL)
+    {
+        fprintf(stderr, "error: cannot create helper thread: %s\n",
+                rtems_status_text (sc));
+        return -1;
+    }
+
+    sc = rtems_task_start (id,
+                           rtems_pcap_loop_thread,
+                           &pcap_loop_args);
+    if (sc != RTEMS_SUCCESSFUL)
+    {
+        fprintf(stderr, "error: cannot start helper thread: %s\n",
+                rtems_status_text (sc));
+        rtems_task_delete (id);
+        return -1;
+    }
+
+    printf("Press ENTER to end\n");
+
+    while (true)
+    {
+        int c = getchar ();
+
+        if ((c == '\r') || (c == '\n') || (c == 'q') || (c == 'Q'))
+        {
+            pcap_breakloop(pd);
+            while (true)
+            {
+                if (!pcap_loop_args.running)
+                    break;
+                usleep(10000);
+            }
+            break;
+        }
+    }
+
+    return 0;
+}
+#define pcap_loop rtems_pcap_loop
+#endif /* __rtems__ */
+
 netdissect_options Gndo;
 netdissect_options *gndo = &Gndo;
 



More information about the vc mailing list