diff --git a/tshark.c b/tshark.c index 62f6642e8a..21036bde6b 100644 --- a/tshark.c +++ b/tshark.c @@ -114,6 +114,9 @@ #include #include #include +#ifdef _WIN32 +#include +#endif #include "extcap.h" @@ -252,7 +255,7 @@ static process_file_status_t process_cap_file(capture_file *, char *, int, gbool static gboolean process_packet_single_pass(capture_file *cf, epan_dissect_t *edt, gint64 offset, wtap_rec *rec, Buffer *buf, guint tap_flags); -static void show_print_file_io_error(int err); +static void show_print_file_io_error(void); static gboolean write_preamble(capture_file *cf); static gboolean print_packet(capture_file *cf, epan_dissect_t *edt); static gboolean write_finale(void); @@ -2238,7 +2241,7 @@ main(int argc, char *argv[]) if (print_packet_info) { if (!write_preamble(&cfile)) { - show_print_file_io_error(errno); + show_print_file_io_error(); exit_status = INVALID_FILE; goto clean_exit; } @@ -2276,7 +2279,7 @@ main(int argc, char *argv[]) if (print_packet_info) { if (!write_finale()) { - show_print_file_io_error(errno); + show_print_file_io_error(); } } @@ -3255,7 +3258,7 @@ process_packet_second_pass(capture_file *cf, epan_dissect_t *edt, fflush(stdout); if (ferror(stdout)) { - show_print_file_io_error(errno); + show_print_file_io_error(); exit(2); } } @@ -3577,7 +3580,7 @@ process_cap_file(capture_file *cf, char *save_file, int out_file_type, /* Set up to print packet information. */ if (print_packet_info) { if (!write_preamble(cf)) { - show_print_file_io_error(errno); + show_print_file_io_error(); status = PROCESS_FILE_NO_FILE_PROCESSED; goto out; } @@ -3758,7 +3761,7 @@ process_cap_file(capture_file *cf, char *save_file, int out_file_type, } else { if (print_packet_info) { if (!write_finale()) { - show_print_file_io_error(errno); + show_print_file_io_error(); status = PROCESS_FILE_ERROR; } } @@ -3858,7 +3861,7 @@ process_packet_single_pass(capture_file *cf, epan_dissect_t *edt, gint64 offset, fflush(stdout); if (ferror(stdout)) { - show_print_file_io_error(errno); + show_print_file_io_error(); exit(2); } } @@ -4402,9 +4405,9 @@ fail: } static void -show_print_file_io_error(int err) +show_print_file_io_error(void) { - switch (err) { + switch (errno) { case ENOSPC: cmdarg_err("Not all the packets could be printed because there is " @@ -4419,13 +4422,37 @@ show_print_file_io_error(int err) #endif case EPIPE: + /* + * This almost certainly means "the next program after us in + * the pipeline exited before we were finished writing", so + * this isn't a real error, it just means we're done. (We + * don't get SIGPIPE because libwireshark ignores SIGPIPE + * to avoid getting killed if writing to the MaxMind process + * gets SIGPIPE because that process died.) + * + * Presumably either that program exited deliberately (for + * example, "head -N" read N lines and printed them), in + * which case there's no error to report, or it terminated + * due to an error or a signal, in which case *that's* the + * error and that error has been reported. + */ + break; + + default: +#ifdef _WIN32 + if (errno == EINVAL && _doserrno == ERROR_NO_DATA) { /* - * This almost certainly means "the next program after us in - * the pipeline exited before we were finished writing", so - * this isn't a real error, it just means we're done. (We - * don't get SIGPIPE because libwireshark ignores SIGPIPE - * to avoid getting killed if writing to the MaxMind process - * gets SIGPIPE because that process died.) + * XXX - on Windows, a write to a pipe where the read side + * has been closed apparently may return the Windows error + * ERROR_BROKEN_PIPE, which the Visual Studio C library maps + * to EPIPE, or may return the Windows error ERROR_NO_DATA, + * which the Visual Studio C library maps to EINVAL. + * + * Either of those almost certainly means "the next program + * after us in the pipeline exited before we were finished + * writing", so, if _doserrno is ERROR_NO_DATA, this isn't + * a real error, it just means we're done. (Windows doesn't + * SIGPIPE.) * * Presumably either that program exited deliberately (for * example, "head -N" read N lines and printed them), in @@ -4434,10 +4461,19 @@ show_print_file_io_error(int err) * error and that error has been reported. */ break; + } - default: + /* + * It's a different error; report it, but with the error + * message for _doserrno, which will give more detail + * than just "Invalid argument". + */ cmdarg_err("An error occurred while printing packets: %s.", - g_strerror(err)); + win32strerror(_doserrno)); +#else + cmdarg_err("An error occurred while printing packets: %s.", + g_strerror(errno)); +#endif break; } }