aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2016-10-21 22:19:46 -0700
committerGuy Harris <guy@alum.mit.edu>2016-10-22 05:20:22 +0000
commit528894e72f973c5db5dc76c975620754f7bbe5aa (patch)
treebd4fc32180655bd1f9e935a2b75220c80ac8e3dd
parentd16295bc9b48a526f12237467536bac4220e53da (diff)
On UN*X, st_ctime is the last status change time, not the creation time.
That's the time the file's inode last changed, so size changes, permission changes, etc. affect it. It's *not* the time the file was created; most UN*Xes don't provide that. Newer versions of FreeBSD, NetBSD, OpenBSD, and macOS do, but other UN*Xes don't appear to. On Windows, at least according to Microsoft's documentation, st_ctime *is* the creation time. Hopefully that's not the result of confusion on the part of somebody at Microsoft. Change-Id: I20743703f6ef66e40dff9004dc91bed46af6fad0 Reviewed-on: https://code.wireshark.org/review/18378 Reviewed-by: Guy Harris <guy@alum.mit.edu>
-rw-r--r--ConfigureChecks.cmake8
-rw-r--r--cmakeconfig.h.in6
-rw-r--r--configure.ac6
-rw-r--r--fileset.c24
-rw-r--r--ui/gtk/fileset_dlg.c28
-rw-r--r--ui/qt/file_set_dialog.cpp14
6 files changed, 72 insertions, 14 deletions
diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake
index 73c24df239..01273f5cbd 100644
--- a/ConfigureChecks.cmake
+++ b/ConfigureChecks.cmake
@@ -134,9 +134,11 @@ endif()
#Struct members
include(CheckStructHasMember)
-check_struct_has_member("struct sockaddr" sa_len sys/socket.h HAVE_SOCKADDR_SA_LEN)
-check_struct_has_member("struct stat" st_flags sys/stat.h HAVE_STAT_ST_FLAGS)
-check_struct_has_member("struct tm" tm_zone time.h HAVE_STRUCT_TM_TM_ZONE)
+check_struct_has_member("struct sockaddr" sa_len sys/socket.h HAVE_SOCKADDR_SA_LEN)
+check_struct_has_member("struct stat" st_flags sys/stat.h HAVE_STAT_ST_FLAGS)
+check_struct_has_member("struct stat" st_birthtime sys/stat.h HAVE_STAT_ST_BIRTHTIME)
+check_struct_has_member("struct stat" __st_birthtime sys/stat.h HAVE_STAT___ST_BIRTHTIME)
+check_struct_has_member("struct tm" tm_zone time.h HAVE_STRUCT_TM_TM_ZONE)
#Symbols but NOT enums or types
check_symbol_exists(tzname "time.h" HAVE_TZNAME)
diff --git a/cmakeconfig.h.in b/cmakeconfig.h.in
index 71ea10cbd0..c206545335 100644
--- a/cmakeconfig.h.in
+++ b/cmakeconfig.h.in
@@ -318,9 +318,15 @@
/* Define if you have the 'strptime' function. */
#cmakedefine HAVE_STRPTIME 1
+/* Define to 1 if `st_birthtime' is a member of `struct stat'. */
+#cmakedefine HAVE_STRUCT_STAT_ST_BIRTHTIME 1
+
/* Define if st_flags field exists in struct stat */
#cmakedefine HAVE_STAT_ST_FLAGS 1
+/* Define to 1 if `__st_birthtime' is a member of `struct stat'. */
+#cmakedefine HAVE_STRUCT_STAT___ST_BIRTHTIME 1
+
/* Define to 1 if you have the `sysconf' function. */
#cmakedefine HAVE_SYSCONF 1
diff --git a/configure.ac b/configure.ac
index 9805e38f44..d03b3cccfa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2426,6 +2426,12 @@ AC_STRUCT_TIMEZONE
AC_CHECK_MEMBERS([struct stat.st_flags])
+# We need to know whether "struct stat" has an "st_birthtime" member
+# or an "__st_birthtime" member for the file set dialog.
+
+AC_CHECK_MEMBERS([struct stat.st_birthtime])
+AC_CHECK_MEMBERS([struct stat.__st_birthtime])
+
# We need to know whether "struct sockaddr" has an "sa_len" member
# for get_interface_list().
diff --git a/fileset.c b/fileset.c
index b1e636c3d5..06cf335f9c 100644
--- a/fileset.c
+++ b/fileset.c
@@ -186,7 +186,19 @@ fileset_update_file(const char *path)
if (entry_list) {
entry = (fileset_entry *) entry_list->data;
+#ifdef __WIN32
+ /* Microsoft's documentation says this is the creation time */
entry->ctime = buf.st_ctime;
+#else /* _WIN32 */
+ /* UN*X - do we have a creation time? */
+#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIME)
+ entry->ctime = buf.st_birthtime;
+#elif defined(HAVE_STRUCT_STAT___ST_BIRTHTIME)
+ entry->ctime = buf.__st_birthtime;
+#else /* nothing */
+ entry->ctime = 0;
+#endif /* creation time on UN*X */
+#endif /* _WIN32 */
entry->mtime = buf.st_mtime;
entry->size = buf.st_size;
}
@@ -220,7 +232,19 @@ fileset_add_file(const char *dirname, const char *fname, gboolean current)
entry->fullname = g_strdup(path);
entry->name = g_strdup(fname);
+#ifdef __WIN32
+ /* Microsoft's documentation says this is the creation time */
entry->ctime = buf.st_ctime;
+#else /* _WIN32 */
+ /* UN*X - do we have a creation time? */
+#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIME)
+ entry->ctime = buf.st_birthtime;
+#elif defined(HAVE_STRUCT_STAT___ST_BIRTHTIME)
+ entry->ctime = buf.__st_birthtime;
+#else /* nothing */
+ entry->ctime = 0;
+#endif /* creation time on UN*X */
+#endif /* _WIN32 */
entry->mtime = buf.st_mtime;
entry->size = buf.st_size;
entry->current = current;
diff --git a/ui/gtk/fileset_dlg.c b/ui/gtk/fileset_dlg.c
index cc28f2b152..540da82fdd 100644
--- a/ui/gtk/fileset_dlg.c
+++ b/ui/gtk/fileset_dlg.c
@@ -158,15 +158,25 @@ fileset_dlg_add_file(fileset_entry *entry, void *window _U_) {
created = fileset_dlg_name2date_dup(entry->name);
if (!created) {
/* if this file doesn't follow the file set pattern, */
- /* use the creation time of that file */
- local = localtime(&entry->ctime);
- if (local != NULL) {
- created = g_strdup_printf("%04u-%02u-%02u %02u:%02u:%02u",
- local->tm_year+1900, local->tm_mon+1, local->tm_mday,
- local->tm_hour, local->tm_min, local->tm_sec);
- } else {
- created = g_strdup("Time not representable");
- }
+ /* use the creation time of that file if available */
+ /*
+ * macOS provides 0 if the file system doesn't support the
+ * creation time; FreeBSD provides -1.
+ *
+ * If this OS doesn't provide the creation time with stat(),
+ * it will be 0.
+ */
+ if (entry->ctime > 0) {
+ local = localtime(&entry->ctime);
+ if (local != NULL) {
+ created = g_strdup_printf("%04u-%02u-%02u %02u:%02u:%02u",
+ local->tm_year+1900, local->tm_mon+1, local->tm_mday,
+ local->tm_hour, local->tm_min, local->tm_sec);
+ } else {
+ created = g_strdup("Time not representable");
+ }
+ } else
+ created = g_strdup("Not available");
}
local = localtime(&entry->mtime);
diff --git a/ui/qt/file_set_dialog.cpp b/ui/qt/file_set_dialog.cpp
index 525d446e7d..f62f8ce8c9 100644
--- a/ui/qt/file_set_dialog.cpp
+++ b/ui/qt/file_set_dialog.cpp
@@ -103,9 +103,19 @@ void FileSetDialog::addFile(fileset_entry *entry) {
created = nameToDate(entry->name);
if(created.length() < 1) {
/* if this file doesn't follow the file set pattern, */
- /* use the creation time of that file */
+ /* use the creation time of that file if available */
/* http://en.wikipedia.org/wiki/ISO_8601 */
- created = QDateTime::fromTime_t(entry->ctime).toLocalTime().toString("yyyy-MM-dd HH:mm:ss");
+ /*
+ * macOS provides 0 if the file system doesn't support the
+ * creation time; FreeBSD provides -1.
+ *
+ * If this OS doesn't provide the creation time with stat(),
+ * it will be 0.
+ */
+ if (entry->ctime > 0)
+ created = QDateTime::fromTime_t(entry->ctime).toLocalTime().toString("yyyy-MM-dd HH:mm:ss");
+ else
+ created = "Not available";
}
modified = QDateTime::fromTime_t(entry->mtime).toLocalTime().toString("yyyy-MM-dd HH:mm:ss");