diff options
author | Guy Harris <guy@alum.mit.edu> | 2002-01-03 22:03:24 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2002-01-03 22:03:24 +0000 |
commit | b1f4093d1a9b94a5eab7d78e59c1ea27ab388234 (patch) | |
tree | 04392a3df5637d3f8de4eb62c3270de49013dc5f /tethereal.c | |
parent | 98b2ecb30478f423a7d7157ff247003095a8a1bd (diff) | |
download | wireshark-b1f4093d1a9b94a5eab7d78e59c1ea27ab388234.tar.gz |
Make the "go" member of the "loop_data" structure in Ethereal a
"gboolean", as it's a Boolean value, and move it to the beginning of the
structure in Tethereal, as it is in Ethereal.
From Graeme Hewson:
Check for "pcap_dispatch()" returning -1, meaning an error
occurred; if it does, stop capturing, and report the error.
If we get a signal in tethereal, stop the capture with a
"longjmp()", rather than by clearning the "go" flag;
"pcap_dispatch()", on many platforms, keeps reading rather than
returning a captured packet count of 0 if the system call to
read packets returns -1 with an errno of EINTR, so the
"pcap_dispatch()" won't be broken out of if the signal handler
returns.
Fix a typo in an error message.
svn path=/trunk/; revision=4471
Diffstat (limited to 'tethereal.c')
-rw-r--r-- | tethereal.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/tethereal.c b/tethereal.c index fe4a073d29..e17f5e0fa1 100644 --- a/tethereal.c +++ b/tethereal.c @@ -1,6 +1,6 @@ /* tethereal.c * - * $Id: tethereal.c,v 1.112 2001/12/21 20:32:53 guy Exp $ + * $Id: tethereal.c,v 1.113 2002/01/03 22:03:24 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -57,6 +57,7 @@ #ifdef HAVE_LIBPCAP #include <pcap.h> +#include <setjmp.h> #endif #ifdef HAVE_LIBZ @@ -122,10 +123,11 @@ static gboolean line_buffered; #ifdef HAVE_LIBPCAP typedef struct _loop_data { + gboolean go; /* TRUE as long as we're supposed to keep capturing */ gint linktype; pcap_t *pch; wtap_dumper *pdh; - gboolean go; + jmp_buf stopenv; } loop_data; static loop_data ld; @@ -755,14 +757,15 @@ main(int argc, char *argv[]) /* Do the low-level work of a capture. Returns TRUE if it succeeds, FALSE otherwise. */ static int -capture(int packet_count, int out_file_type) +capture(volatile int packet_count, int out_file_type) { gchar open_err_str[PCAP_ERRBUF_SIZE]; gchar lookup_net_err_str[PCAP_ERRBUF_SIZE]; bpf_u_int32 netnum, netmask; struct bpf_program fcode; void (*oldhandler)(int); - int err, inpkts; + int err; + volatile int inpkts = 0; char errmsg[1024+1]; condition *cnd_stop_capturesize; condition *cnd_stop_timeout; @@ -848,7 +851,7 @@ capture(int packet_count, int out_file_type) * we just warn the user, and punt and use 0. */ fprintf(stderr, - "Warning: Couldn't obtain netmask info (%s)\n.", lookup_net_err_str); + "Warning: Couldn't obtain netmask info (%s).\n", lookup_net_err_str); netmask = 0; } if (pcap_compile(ld.pch, &fcode, cfile.cfilter, 1, netmask) < 0) { @@ -923,12 +926,15 @@ capture(int packet_count, int out_file_type) if (packet_count == 0) packet_count = -1; /* infinite capturng */ - ld.go = TRUE; + if (!setjmp(ld.stopenv)) + ld.go = TRUE; + else + ld.go = FALSE; while (ld.go) { if (packet_count > 0) packet_count--; inpkts = pcap_dispatch(ld.pch, 1, capture_pcap_cb, (u_char *) &ld); - if (packet_count == 0) { + if (packet_count == 0 || inpkts < 0) { ld.go = FALSE; } else if (cnd_eval(cnd_stop_timeout) == TRUE) { /* The specified capture time has elapsed; stop the capture. */ @@ -1038,9 +1044,11 @@ capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr, static void capture_cleanup(int signum) { - /* Just set the loop flag to false. This will initiate - a proper termination. */ - ld.go = FALSE; + /* Longjmp back to the starting point; "pcap_dispatch()", on many + platforms, just keeps looping if it gets EINTR, so if we set + "ld.go" to FALSE and return, we won't break out of it and quit + capturing. */ + longjmp(ld.stopenv, 1); } #endif /* HAVE_LIBPCAP */ |