summaryrefslogtreecommitdiff
path: root/wiretap/file_access.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2015-11-10 02:01:43 -0800
committerGuy Harris <guy@alum.mit.edu>2015-11-10 10:11:50 +0000
commit827b7dd75680b26e2bfddb0dac2f42f1dad69e7a (patch)
tree6e2f0010572a5073789163fd0abbf270f739e44a /wiretap/file_access.c
parent630ccbe2d74338bac6d8abe69705cf0401baa8c1 (diff)
downloadwireshark-827b7dd75680b26e2bfddb0dac2f42f1dad69e7a.tar.gz
Skip only the actual file descriptor close when writing to stdout.
Have a "this is stdout" flag for a wtap_dumper, and have "open the standard output for dumping" routines that set that flag. When closing a wtap_dumper, do most of the work regardless of whether we're writing to the standard output or not (so that everything gets written out) and only skip the closing of the underlying file descriptor. Change-Id: I9f7e4d142b3bd598055d806b7ded1cb4c378de8e Reviewed-on: https://code.wireshark.org/review/11673 Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'wiretap/file_access.c')
-rw-r--r--wiretap/file_access.c110
1 files changed, 82 insertions, 28 deletions
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);
}
}