aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2001-02-18 03:38:44 +0000
committerGuy Harris <guy@alum.mit.edu>2001-02-18 03:38:44 +0000
commitfd6cd6f9bcf034493d0799e99982d7c3e10a402e (patch)
treed8fc2b54d561d3a98a3f27cb0e022584af3002d6
parent9be2e1df55261e341cb44f08cba3e56a8438e9cf (diff)
In the MSVC++ 6.0 C library, "line-buffered" doesn't mean what one might
expect - it means "same as fully-buffered". This means that the "-l" flag is a no-op on Windows. Instead of setting line-buffered mode with "setvbuf()", set a flag and, if that flag is set, flush the standard output after the information for ever packet is printed; this isn't "line-buffered", either, but, as the reason for doing line-buffering is to allow the output of Tethereal to be piped to a program and to have that program see the output for a packet as soon as the packet is seen and dissected, it should be just as good as line-buffered. svn path=/trunk/; revision=3047
-rw-r--r--doc/tethereal.pod.template20
-rw-r--r--tethereal.c41
2 files changed, 53 insertions, 8 deletions
diff --git a/doc/tethereal.pod.template b/doc/tethereal.pod.template
index c7d5c6caa8..298afa81eb 100644
--- a/doc/tethereal.pod.template
+++ b/doc/tethereal.pod.template
@@ -132,11 +132,21 @@ interfaces, B<Tethereal> reports an error and doesn't start the capture.
=item -l
-Make the standard output line buffered. This may be useful when piping
-the output of B<Tethereal> to another program, as it means that the
-program to which the output is piped will see lines of output as soon as
-B<Tethereal> generates those lines, rather than seeing them only when
-the standard output buffer containing those lines fills up.
+Flush the standard output after the information for each packet is
+printed. (This is not, strictly speaking, line-buffered if B<-V>
+was specified; however, it is the same as line-buffered if B<-V> wasn't
+specified, as only one line is printed for each packet, and, as B<-l> is
+normally used when piping a live capture to a program or script, so that
+output for a packet shows up as soon as the packet is seen and
+dissected, it should work just as well as true line-buffering. We do
+this as a workaround for a deficiency in the Microsoft Visual C++ C
+library.)
+
+This may be useful when piping the output of B<Tethereal> to another
+program, as it means that the program to which the output is piped will
+see the dissected data for a packet as soon as B<Tethereal> sees the
+packet and generates that output, rather than seeing it only when the
+standard output buffer containing that data fills up.
=item -n
diff --git a/tethereal.c b/tethereal.c
index e3f934337d..39fc756caa 100644
--- a/tethereal.c
+++ b/tethereal.c
@@ -1,6 +1,6 @@
/* tethereal.c
*
- * $Id: tethereal.c,v 1.67 2001/02/11 21:29:03 guy Exp $
+ * $Id: tethereal.c,v 1.68 2001/02/18 03:38:42 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -99,6 +99,7 @@ static guint32 prevsec, prevusec;
static gchar comp_info_str[256];
static gboolean verbose;
static gboolean print_hex;
+static gboolean line_buffered;
#ifdef HAVE_LIBPCAP
typedef struct _loop_data {
@@ -332,8 +333,19 @@ main(int argc, char *argv[])
arg_error = TRUE;
#endif
break;
- case 'l': /* Line-buffer standard output */
- setvbuf(stdout, NULL, _IOLBF, 0);
+ case 'l': /* "Line-buffer" standard output */
+ /* This isn't line-buffering, strictly speaking, it's just
+ flushing the standard output after the information for
+ each packet is printed; however, that should be good
+ enough for all the purposes to which "-l" is put.
+
+ See the comment in "wtap_dispatch_cb_print()" for an
+ explanation of why we do that, and why we don't just
+ use "setvbuf()" to make the standard output line-buffered
+ (short version: in Windows, "line-buffered" is the same
+ as "fully-buffered", and the output buffer is only flushed
+ when it fills up). */
+ line_buffered = TRUE;
break;
case 'n': /* No name resolution */
g_resolving_actif = 0;
@@ -1250,6 +1262,29 @@ wtap_dispatch_cb_print(u_char *user, const struct wtap_pkthdr *phdr, int offset,
}
fdata.cinfo = NULL;
}
+
+ /* The ANSI C standard does not appear to *require* that a line-buffered
+ stream be flushed to the host environment whenever a newline is
+ written, it just says that, on such a stream, characters "are
+ intended to be transmitted to or from the host environment as a
+ block when a new-line character is encountered".
+
+ The Visual C++ 6.0 C implementation doesn't do what is intended;
+ even if you set a stream to be line-buffered, it still doesn't
+ flush the buffer at the end of every line.
+
+ So, if the "-l" flag was specified, we flush the standard output
+ at the end of a packet. This will do the right thing if we're
+ printing packet summary lines, and, as we print the entire protocol
+ tree for a single packet without waiting for anything to happen,
+ it should be as good as line-buffered mode if we're printing
+ protocol trees. (The whole reason for the "-l" flag in either
+ tcpdump or Tethereal is to allow the output of a live capture to
+ be piped to a program or script and to have that script see the
+ information for the packet as soon as it's printed, rather than
+ having to wait until a standard I/O buffer fills up. */
+ if (line_buffered)
+ fflush(stdout);
if (protocol_tree != NULL)
proto_tree_free(protocol_tree);