summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2016-12-03 14:17:08 -0800
committerGuy Harris <guy@alum.mit.edu>2016-12-03 22:17:41 +0000
commit3309c08cd03a16438e6189bf4547ca172f90330a (patch)
tree9223705a61ea3b6adcbe3c931e3a7a0af4d17a54
parenta0d03ce1e70144fe713df9e03b30bc8126d764a5 (diff)
downloadwireshark-3309c08cd03a16438e6189bf4547ca172f90330a.tar.gz
When opening the standard output for writing, dup it.
That way, we can close the resulting wtap_dumper the same way we close any other wtap_dumper, including closing the FD, rather than trying to do everything *except* closing the FD (which is tricky for a FILE *). Change-Id: I8cb66e32784d73e598b2e8720a12f9bdab1c6205 Reviewed-on: https://code.wireshark.org/review/19054 Reviewed-by: Guy Harris <guy@alum.mit.edu>
-rw-r--r--wiretap/file_access.c68
-rw-r--r--wiretap/file_wrappers.c16
-rw-r--r--wiretap/file_wrappers.h2
-rw-r--r--wiretap/wtap-int.h1
4 files changed, 31 insertions, 56 deletions
diff --git a/wiretap/file_access.c b/wiretap/file_access.c
index e3eecf79a0..dba7e32b5c 100644
--- a/wiretap/file_access.c
+++ b/wiretap/file_access.c
@@ -2392,45 +2392,42 @@ wtap_dump_open_stdout_ng(int file_type_subtype, int encap, int snaplen,
wtapng_iface_descriptions_t *idb_inf,
GArray* nrb_hdrs, int *err)
{
+ int new_fd;
wtap_dumper *wdh;
- WFILE_T fh;
- /* Allocate and initialize a data structure for the output stream. */
- wdh = wtap_dump_init_dumper(file_type_subtype, encap, snaplen, compressed,
- shb_hdrs, idb_inf, nrb_hdrs, err);
- if (wdh == NULL)
+ /*
+ * Duplicate the file descriptor, so that we can close the
+ * wtap_dumper handle the same way we close any other
+ * wtap_dumper handle, without closing the standard output.
+ */
+ new_fd = ws_dup(1);
+ if (new_fd == -1) {
+ /* dup failed */
+ *err = errno;
+ close(new_fd);
return NULL;
-
+ }
#ifdef _WIN32
/*
- * Put the standard output into binary mode.
+ * Put the new descriptor into binary mode.
*
* XXX - even if the file format we're writing is a text
* format?
*/
- if (_setmode(1, O_BINARY) == -1) {
+ if (_setmode(new_fd, O_BINARY) == -1) {
/* "Should not happen" */
*err = errno;
- g_free(wdh);
- return NULL; /* couldn't put standard output in binary mode */
+ close(new_fd);
+ return NULL;
}
#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, 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);
- g_free(wdh);
+fprintf(stderr, "new_fd is %d\n", new_fd);
+ wdh = wtap_dump_fdopen_ng(new_fd, file_type_subtype, encap, snaplen,
+ compressed, shb_hdrs, idb_inf, nrb_hdrs, err);
+ if (wdh == NULL) {
+ /* Failed; close the new FD */
+ close(new_fd);
return NULL;
}
return wdh;
@@ -2681,24 +2678,11 @@ static int
wtap_dump_file_close(wtap_dumper *wdh)
{
#ifdef HAVE_ZLIB
- if(wdh->compressed) {
- /*
- * Tell gzwfile_close() whether to close the descriptor
- * or not.
- */
- return gzwfile_close((GZWFILE_T)wdh->fh, wdh->is_stdout);
- } else
+ if(wdh->compressed)
+ return gzwfile_close((GZWFILE_T)wdh->fh);
+ else
#endif
- {
- /*
- * 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);
- }
+ return fclose((FILE *)wdh->fh);
}
gint64
diff --git a/wiretap/file_wrappers.c b/wiretap/file_wrappers.c
index c466c5f223..85d619ac8e 100644
--- a/wiretap/file_wrappers.c
+++ b/wiretap/file_wrappers.c
@@ -1709,15 +1709,9 @@ gzwfile_flush(GZWFILE_T state)
}
/* Flush out all data written, and close the file. Returns a Wiretap
- 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). */
+ error on failure; returns 0 on success. */
int
-gzwfile_close(GZWFILE_T state, gboolean is_stdout)
+gzwfile_close(GZWFILE_T state)
{
int ret = 0;
@@ -1728,10 +1722,8 @@ gzwfile_close(GZWFILE_T state, gboolean is_stdout)
g_free(state->out);
g_free(state->in);
state->err = Z_OK;
- if (!is_stdout) {
- if (ws_close(state->fd) == -1 && ret == 0)
- ret = errno;
- }
+ 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 d53b47c09e..a7aca97643 100644
--- a/wiretap/file_wrappers.h
+++ b/wiretap/file_wrappers.h
@@ -52,7 +52,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, gboolean is_stdout);
+extern int gzwfile_close(GZWFILE_T state);
extern int gzwfile_geterr(GZWFILE_T state);
#endif /* HAVE_ZLIB */
diff --git a/wiretap/wtap-int.h b/wiretap/wtap-int.h
index e600b5d8a7..0897e9db00 100644
--- a/wiretap/wtap-int.h
+++ b/wiretap/wtap-int.h
@@ -97,7 +97,6 @@ typedef gboolean (*subtype_finish_func)(struct wtap_dumper*, int*);
struct wtap_dumper {
WFILE_T fh;
- gboolean is_stdout; /* TRUE if we're writing to the standard output */
int file_type_subtype;
int snaplen;
int encap;