diff options
-rw-r--r-- | editcap.c | 8 | ||||
-rw-r--r-- | randpkt.c | 2 | ||||
-rw-r--r-- | reordercap.c | 4 | ||||
-rw-r--r-- | tshark.c | 4 | ||||
-rw-r--r-- | wiretap/file_access.c | 110 | ||||
-rw-r--r-- | wiretap/file_wrappers.c | 16 | ||||
-rw-r--r-- | wiretap/file_wrappers.h | 2 | ||||
-rw-r--r-- | wiretap/wtap-int.h | 1 | ||||
-rw-r--r-- | wiretap/wtap.h | 26 |
9 files changed, 131 insertions, 42 deletions
@@ -898,10 +898,10 @@ editcap_dump_open(const char *filename, guint32 snaplen, if (strcmp(filename, "-") == 0) { /* Write to the standard output. */ - pdh = wtap_dump_fdopen_ng(1, out_file_type_subtype, out_frame_type, - snaplen, FALSE /* compressed */, - shb_hdr, idb_inf, nrb_hdr, - write_err); + pdh = wtap_dump_open_stdout_ng(out_file_type_subtype, out_frame_type, + snaplen, FALSE /* compressed */, + shb_hdr, idb_inf, nrb_hdr, + write_err); } else { pdh = wtap_dump_open_ng(filename, out_file_type_subtype, out_frame_type, snaplen, FALSE /* compressed */, @@ -636,7 +636,7 @@ static void randpkt_example_init(randpkt_example* example, char* produce_filenam if (strcmp(produce_filename, "-") == 0) { /* Write to the standard output. */ - example->dump = wtap_dump_fdopen(1, WTAP_FILE_TYPE_SUBTYPE_PCAP, + example->dump = wtap_dump_open_stdout(WTAP_FILE_TYPE_SUBTYPE_PCAP, example->sample_wtap_encap, produce_max_bytes, FALSE /* compressed */, &err); example->filename = "the standard output"; } else { diff --git a/reordercap.c b/reordercap.c index efbbfdaf36..fef413dd75 100644 --- a/reordercap.c +++ b/reordercap.c @@ -276,8 +276,8 @@ DIAG_ON(cast-qual) /* Open outfile (same filetype/encap as input file) */ if (strcmp(outfile, "-") == 0) { - pdh = wtap_dump_fdopen_ng(1, wtap_file_type_subtype(wth), wtap_file_encap(wth), - 65535, FALSE, shb_hdr, idb_inf, nrb_hdr, &err); + pdh = wtap_dump_open_stdout_ng(wtap_file_type_subtype(wth), wtap_file_encap(wth), + 65535, FALSE, shb_hdr, idb_inf, nrb_hdr, &err); outfile = "standard output"; } else { pdh = wtap_dump_open_ng(outfile, wtap_file_type_subtype(wth), wtap_file_encap(wth), @@ -3201,7 +3201,7 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type, tshark_debug("tshark: writing PCAP format to %s", save_file); if (strcmp(save_file, "-")) { /* Write to the standard output. */ - pdh = wtap_dump_fdopen(1, out_file_type, linktype, + pdh = wtap_dump_open_stdout(out_file_type, linktype, snapshot_length, FALSE /* compressed */, &err); } else { pdh = wtap_dump_open(save_file, out_file_type, linktype, @@ -3212,7 +3212,7 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type, tshark_debug("tshark: writing format type %d, to %s", out_file_type, save_file); if (strcmp(save_file, "-")) { /* Write to the standard output. */ - pdh = wtap_dump_fdopen_ng(1, out_file_type, linktype, + pdh = wtap_dump_open_stdout_ng(out_file_type, linktype, snapshot_length, FALSE /* compressed */, shb_hdr, idb_inf, nrb_hdr, &err); } else { pdh = wtap_dump_open_ng(save_file, out_file_type, linktype, diff --git a/wiretap/file_access.c b/wiretap/file_access.c index c667118408..8a965f100d 100644 --- a/wiretap/file_access.c +++ b/wiretap/file_access.c @@ -2231,10 +2231,8 @@ wtap_dump_open_ng(const char *filename, int file_type_subtype, int encap, if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) { /* Get rid of the file we created; we couldn't finish opening it. */ - if (wdh->fh != stdout) { - wtap_dump_file_close(wdh); - ws_unlink(filename); - } + wtap_dump_file_close(wdh); + ws_unlink(filename); g_free(wdh); return NULL; } @@ -2267,27 +2265,78 @@ wtap_dump_fdopen_ng(int fd, int file_type_subtype, int encap, int snaplen, if (wdh == NULL) return NULL; + /* In case "fopen()" fails but doesn't set "errno", set "errno" + to a generic "the open failed" error. */ + errno = WTAP_ERR_CANT_OPEN; + fh = wtap_dump_file_fdopen(wdh, fd); + if (fh == NULL) { + *err = errno; + g_free(wdh); + return NULL; /* can't create standard I/O stream */ + } + wdh->fh = fh; + + if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) { + wtap_dump_file_close(wdh); + g_free(wdh); + return NULL; + } + return wdh; +} + +wtap_dumper * +wtap_dump_open_stdout(int file_type_subtype, int encap, int snaplen, + gboolean compressed, int *err) +{ + return wtap_dump_open_stdout_ng(file_type_subtype, encap, snaplen, compressed, NULL, NULL, NULL, err); +} + +wtap_dumper * +wtap_dump_open_stdout_ng(int file_type_subtype, int encap, int snaplen, + gboolean compressed, wtapng_section_t *shb_hdr, + wtapng_iface_descriptions_t *idb_inf, + wtapng_name_res_t *nrb_hdr, int *err) +{ + wtap_dumper *wdh; + WFILE_T fh; + + /* Check whether we can open a capture file with that file type + and that encapsulation. */ + if (!wtap_dump_open_check(file_type_subtype, encap, compressed, err)) + return NULL; + + /* Allocate and initialize a data structure for the output stream. */ + wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed, + shb_hdr, idb_inf, nrb_hdr, err); + if (wdh == NULL) + return NULL; + #ifdef _WIN32 - if (fd == 1) { - if (_setmode(fileno(stdout), O_BINARY) == -1) { - /* "Should not happen" */ - *err = errno; - g_free(wdh); - return NULL; /* couldn't put standard output in binary mode */ - } + /* + * Put the standard output into binary mode. + * + * XXX - even if the file format we're writing is a text + * format? + */ + if (_setmode(1, O_BINARY) == -1) { + /* "Should not happen" */ + *err = errno; + g_free(wdh); + return NULL; /* couldn't put standard output in binary mode */ } #endif /* In case "fopen()" fails but doesn't set "errno", set "errno" to a generic "the open failed" error. */ errno = WTAP_ERR_CANT_OPEN; - fh = wtap_dump_file_fdopen(wdh, fd); + fh = wtap_dump_file_fdopen(wdh, 1); if (fh == NULL) { *err = errno; g_free(wdh); return NULL; /* can't create standard I/O stream */ } wdh->fh = fh; + wdh->is_stdout = TRUE; if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) { wtap_dump_file_close(wdh); @@ -2424,21 +2473,15 @@ wtap_dump_close(wtap_dumper *wdh, int *err) ret = FALSE; } errno = WTAP_ERR_CANT_CLOSE; - /* Don't close stdout */ - if (wdh->fh != stdout) { - if (wtap_dump_file_close(wdh) == EOF) { - if (ret) { - /* The per-format close function succeeded, - but the fclose didn't. Save the reason - why, if our caller asked for it. */ - if (err != NULL) - *err = errno; - } - ret = FALSE; + if (wtap_dump_file_close(wdh) == EOF) { + if (ret) { + /* The per-format finish function succeeded, + but the stream close didn't. Save the + reason why, if our caller asked for it. */ + if (err != NULL) + *err = errno; } - } else { - /* as we don't close stdout, at least try to flush it */ - wtap_dump_flush(wdh); + ret = FALSE; } if (wdh->priv != NULL) g_free(wdh->priv); @@ -2548,11 +2591,22 @@ wtap_dump_file_close(wtap_dumper *wdh) { #ifdef HAVE_LIBZ if(wdh->compressed) { - return gzwfile_close((GZWFILE_T)wdh->fh); + /* + * Tell gzwfile_close() whether to close the descriptor + * or not. + */ + return gzwfile_close((GZWFILE_T)wdh->fh, wdh->is_stdout); } else #endif { - return fclose((FILE *)wdh->fh); + /* + * Don't close the standard output. + * + * XXX - this really should do everything fclose() does, + * including freeing all allocated data structures, + * *except* for actually closing the file descriptor. + */ + return wdh->is_stdout ? fflush((FILE *)wdh->fh) : fclose((FILE *)wdh->fh); } } diff --git a/wiretap/file_wrappers.c b/wiretap/file_wrappers.c index 5b4cbd27da..5918a55f6f 100644 --- a/wiretap/file_wrappers.c +++ b/wiretap/file_wrappers.c @@ -1719,9 +1719,15 @@ gzwfile_flush(GZWFILE_T state) } /* Flush out all data written, and close the file. Returns a Wiretap - error on failure; returns 0 on success. */ + error on failure; returns 0 on success. + + If is_stdout is true, do all of that except for closing the file + descriptor, as we don't want to close the standard output file + descriptor out from under the program (even though, if the program + is writing a capture file to the standard output, it shouldn't be + doing anything *else* on the standard output). */ int -gzwfile_close(GZWFILE_T state) +gzwfile_close(GZWFILE_T state, gboolean is_stdout) { int ret = 0; @@ -1732,8 +1738,10 @@ gzwfile_close(GZWFILE_T state) g_free(state->out); g_free(state->in); state->err = Z_OK; - if (ws_close(state->fd) == -1 && ret == 0) - ret = errno; + if (!is_stdout) { + if (ws_close(state->fd) == -1 && ret == 0) + ret = errno; + } g_free(state); return ret; } diff --git a/wiretap/file_wrappers.h b/wiretap/file_wrappers.h index 7f3cdc4205..42df4e4e66 100644 --- a/wiretap/file_wrappers.h +++ b/wiretap/file_wrappers.h @@ -53,7 +53,7 @@ extern GZWFILE_T gzwfile_open(const char *path); extern GZWFILE_T gzwfile_fdopen(int fd); extern guint gzwfile_write(GZWFILE_T state, const void *buf, guint len); extern int gzwfile_flush(GZWFILE_T state); -extern int gzwfile_close(GZWFILE_T state); +extern int gzwfile_close(GZWFILE_T state, gboolean is_stdout); extern int gzwfile_geterr(GZWFILE_T state); #endif /* HAVE_LIBZ */ diff --git a/wiretap/wtap-int.h b/wiretap/wtap-int.h index 91656bdfaa..87d5f4b0e9 100644 --- a/wiretap/wtap-int.h +++ b/wiretap/wtap-int.h @@ -95,6 +95,7 @@ typedef gboolean (*subtype_finish_func)(struct wtap_dumper*, int*); struct wtap_dumper { WFILE_T fh; + gboolean is_stdout; int file_type_subtype; int snaplen; int encap; diff --git a/wiretap/wtap.h b/wiretap/wtap.h index 253f3c9a7f..37dfce7918 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -1936,6 +1936,7 @@ wtap_dumper* wtap_dump_fdopen(int fd, int file_type_subtype, int encap, int snap * wtap_dump_close() is called, but will not be free'd by the dumper. If * you created them, you must free them yourself after wtap_dump_close(). * + * @param fd The file descriptor for which the dumper should be created. * @param file_type_subtype The WTAP_FILE_TYPE_SUBTYPE_XXX file type. * @param encap The WTAP_ENCAP_XXX encapsulation type (WTAP_ENCAP_PER_PACKET for multi) * @param snaplen The maximum packet capture length. @@ -1951,6 +1952,31 @@ wtap_dumper* wtap_dump_fdopen_ng(int fd, int file_type_subtype, int encap, int s gboolean compressed, wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf, wtapng_name_res_t *nrb_hdr, int *err); +WS_DLL_PUBLIC +wtap_dumper* wtap_dump_open_stdout(int file_type_subtype, int encap, int snaplen, + gboolean compressed, int *err); + +/** + * @brief Creates a dumper for the standard output. + * + * @note The shb_hdr, idb_inf, and nrb_hdr arguments will be used until + * wtap_dump_close() is called, but will not be free'd by the dumper. If + * you created them, you must free them yourself after wtap_dump_close(). + * + * @param file_type_subtype The WTAP_FILE_TYPE_SUBTYPE_XXX file type. + * @param encap The WTAP_ENCAP_XXX encapsulation type (WTAP_ENCAP_PER_PACKET for multi) + * @param snaplen The maximum packet capture length. + * @param compressed True if file should be compressed. + * @param shb_hdr The section header block information, or NULL. + * @param idb_inf The interface description information, or NULL. + * @param nrb_hdr The name resolution comment/custom_opts information, or NULL. + * @param[out] err Will be set to an error code on failure. + * @return The newly created dumper object, or NULL on failure. + */ +WS_DLL_PUBLIC +wtap_dumper* wtap_dump_open_stdout_ng(int file_type_subtype, int encap, int snaplen, + gboolean compressed, wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf, + wtapng_name_res_t *nrb_hdr, int *err); WS_DLL_PUBLIC gboolean wtap_dump(wtap_dumper *, const struct wtap_pkthdr *, const guint8 *, |