diff options
author | Guy Harris <guy@alum.mit.edu> | 2016-12-03 14:17:08 -0800 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2016-12-03 22:17:41 +0000 |
commit | 3309c08cd03a16438e6189bf4547ca172f90330a (patch) | |
tree | 9223705a61ea3b6adcbe3c931e3a7a0af4d17a54 | |
parent | a0d03ce1e70144fe713df9e03b30bc8126d764a5 (diff) | |
download | wireshark-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.c | 68 | ||||
-rw-r--r-- | wiretap/file_wrappers.c | 16 | ||||
-rw-r--r-- | wiretap/file_wrappers.h | 2 | ||||
-rw-r--r-- | wiretap/wtap-int.h | 1 |
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; |