aboutsummaryrefslogtreecommitdiffstats
path: root/wiretap/file_access.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2012-06-01 08:45:39 +0000
committerGuy Harris <guy@alum.mit.edu>2012-06-01 08:45:39 +0000
commitb8646937d41b972178e060e40dd32e4c53a9d889 (patch)
tree4754551658404e8290d3330b794fc82e48d3ff31 /wiretap/file_access.c
parent5f4a8a8c321cdc1916d61d64c92068789f3861d2 (diff)
Move wtap_fdreopen() to file_access.c for now, as it requires many of
the same #includes. svn path=/trunk/; revision=42963
Diffstat (limited to 'wiretap/file_access.c')
-rw-r--r--wiretap/file_access.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/wiretap/file_access.c b/wiretap/file_access.c
index 6e88b69d96..30e9d6164f 100644
--- a/wiretap/file_access.c
+++ b/wiretap/file_access.c
@@ -405,6 +405,120 @@ success:
return wth;
}
+/*
+ * Given the pathname of the file we just closed with wtap_fdclose(), attempt
+ * to reopen that file and assign the new file descriptor(s) to the sequential
+ * stream and, if do_random is TRUE, to the random stream. Used on Windows
+ * after the rename of a file we had open was done or if the rename of a
+ * file on top of a file we had open failed.
+ */
+gboolean
+wtap_fdreopen(wtap *wth, const char *filename, int *err, gboolean do_random)
+{
+ int fd;
+ ws_statb64 statb;
+ gboolean use_stdin = FALSE;
+
+ /* open standard input if filename is '-' */
+ if (strcmp(filename, "-") == 0)
+ use_stdin = TRUE;
+
+ /* First, make sure the file is valid */
+ if (use_stdin) {
+ if (ws_fstat64(0, &statb) < 0) {
+ *err = errno;
+ return FALSE;
+ }
+ } else {
+ if (ws_stat64(filename, &statb) < 0) {
+ *err = errno;
+ return FALSE;
+ }
+ }
+ if (S_ISFIFO(statb.st_mode)) {
+ /*
+ * Opens of FIFOs are allowed only when not opening
+ * for random access.
+ *
+ * XXX - currently, we do seeking when trying to find
+ * out the file type, so we don't actually support
+ * opening FIFOs. However, we may eventually
+ * do buffering that allows us to do at least some
+ * file type determination even on pipes, so we
+ * allow FIFO opens and let things fail later when
+ * we try to seek.
+ */
+ if (do_random) {
+ *err = WTAP_ERR_RANDOM_OPEN_PIPE;
+ return FALSE;
+ }
+ } else if (S_ISDIR(statb.st_mode)) {
+ /*
+ * Return different errors for "this is a directory"
+ * and "this is some random special file type", so
+ * the user can get a potentially more helpful error.
+ */
+ *err = EISDIR;
+ return FALSE;
+ } else if (! S_ISREG(statb.st_mode)) {
+ *err = WTAP_ERR_NOT_REGULAR_FILE;
+ return FALSE;
+ }
+
+ /*
+ * We need two independent descriptors for random access, so
+ * they have different file positions. If we're opening the
+ * standard input, we can only dup it to get additional
+ * descriptors, so we can't have two independent descriptors,
+ * and thus can't do random access.
+ */
+ if (use_stdin && do_random) {
+ *err = WTAP_ERR_RANDOM_OPEN_STDIN;
+ return FALSE;
+ }
+
+ /* Open the file */
+ errno = WTAP_ERR_CANT_OPEN;
+ if (use_stdin) {
+ /*
+ * We dup FD 0, so that we don't have to worry about
+ * a file_close of wth->fh closing the standard
+ * input of the process.
+ */
+ fd = ws_dup(0);
+ if (fd < 0) {
+ *err = errno;
+ return FALSE;
+ }
+#ifdef _WIN32
+ if (_setmode(fd, O_BINARY) == -1) {
+ /* "Shouldn't happen" */
+ *err = errno;
+ return FALSE;
+ }
+#endif
+ if (!(wth->fh = file_fdopen(fd))) {
+ *err = errno;
+ ws_close(fd);
+ return FALSE;
+ }
+ } else {
+ if (!file_fdreopen(wth->fh, filename)) {
+ *err = errno;
+ return FALSE;
+ }
+ }
+
+ if (do_random) {
+ if (!file_fdreopen(wth->random_fh, filename)) {
+ *err = errno;
+ file_fdclose(wth->fh);
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
/* Table of the file types we know about.
Entries must be sorted by WTAP_FILE_xxx values in ascending order */
static const struct file_type_info dump_open_table_base[] = {