aboutsummaryrefslogtreecommitdiff
path: root/jim-file.c
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2016-08-27 14:09:31 +1000
committerSteve Bennett <steveb@workware.net.au>2018-09-21 12:57:41 +1000
commitfd07366b2c527527425dce94d1c337168ea86638 (patch)
tree4e5de3da314e9d70cacfcc818327c5b193d40133 /jim-file.c
parent022f90263261694bbcb98373ad7e5a282ab74453 (diff)
downloadjimtcl-fd07366b2c527527425dce94d1c337168ea86638.zip
jimtcl-fd07366b2c527527425dce94d1c337168ea86638.tar.gz
jimtcl-fd07366b2c527527425dce94d1c337168ea86638.tar.bz2
file: Add microsecond resolution for mtime: mtimeus
Note that actual support is dependent upon the underlying operating system and filesystem. Signed-off-by: Steve Bennett <steveb@workware.net.au>
Diffstat (limited to 'jim-file.c')
-rw-r--r--jim-file.c75
1 files changed, 61 insertions, 14 deletions
diff --git a/jim-file.c b/jim-file.c
index 8185839..dca906d 100644
--- a/jim-file.c
+++ b/jim-file.c
@@ -77,6 +77,13 @@
#define ISWINDOWS 0
#endif
+/* extract nanosecond resolution mtime from struct stat */
+#if defined(HAVE_STRUCT_STAT_ST_MTIMESPEC)
+ #define STAT_MTIME_US(STAT) ((STAT).st_mtimespec.tv_sec * 1000000ll + (STAT).st_mtimespec.tv_nsec / 1000)
+#elif defined(HAVE_STRUCT_STAT_ST_MTIM)
+ #define STAT_MTIME_US(STAT) ((STAT).st_mtim.tv_sec * 1000000ll + (STAT).st_mtim.tv_nsec / 1000)
+#endif
+
/*
*----------------------------------------------------------------------
*
@@ -169,6 +176,9 @@ static int StoreStatData(Jim_Interp *interp, Jim_Obj *varName, const struct stat
AppendStatElement(interp, listObj, "atime", sb->st_atime);
AppendStatElement(interp, listObj, "mtime", sb->st_mtime);
AppendStatElement(interp, listObj, "ctime", sb->st_ctime);
+#ifdef STAT_MTIME_US
+ AppendStatElement(interp, listObj, "mtimeus", STAT_MTIME_US(*sb));
+#endif
Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "type", -1));
Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, JimGetFileType((int)sb->st_mode), -1));
@@ -610,37 +620,65 @@ static int file_cmd_atime(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
return JIM_OK;
}
+/**
+ * Set file atime/mtime to the given time in microseconds since the epoch.
+ */
+static int JimSetFileTimes(Jim_Interp *interp, const char *filename, jim_wide us)
+{
+#ifdef HAVE_UTIMES
+ struct timeval times[2];
+
+ times[1].tv_sec = times[0].tv_sec = us / 1000000;
+ times[1].tv_usec = times[0].tv_usec = us % 1000000;
+
+ if (utimes(filename, times) != 0) {
+ Jim_SetResultFormatted(interp, "can't set time on \"%s\": %s", filename, strerror(errno));
+ return JIM_ERR;
+ }
+ return JIM_OK;
+#else
+ Jim_SetResultString(interp, "Not implemented", -1);
+ return JIM_ERR;
+#endif
+}
+
static int file_cmd_mtime(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
struct stat sb;
if (argc == 2) {
-#ifdef HAVE_UTIMES
- jim_wide newtime;
- struct timeval times[2];
-
- if (Jim_GetWide(interp, argv[1], &newtime) != JIM_OK) {
+ jim_wide secs;
+ if (Jim_GetWide(interp, argv[1], &secs) != JIM_OK) {
return JIM_ERR;
}
+ return JimSetFileTimes(interp, Jim_String(argv[0]), secs * 1000000);
+ }
+ if (file_stat(interp, argv[0], &sb) != JIM_OK) {
+ return JIM_ERR;
+ }
+ Jim_SetResultInt(interp, sb.st_mtime);
+ return JIM_OK;
+}
- times[1].tv_sec = times[0].tv_sec = newtime;
- times[1].tv_usec = times[0].tv_usec = 0;
+#ifdef STAT_MTIME_US
+static int file_cmd_mtimeus(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ struct stat sb;
- if (utimes(Jim_String(argv[0]), times) != 0) {
- Jim_SetResultFormatted(interp, "can't set time on \"%#s\": %s", argv[0], strerror(errno));
+ if (argc == 2) {
+ jim_wide us;
+ if (Jim_GetWide(interp, argv[1], &us) != JIM_OK) {
return JIM_ERR;
}
-#else
- Jim_SetResultString(interp, "Not implemented", -1);
- return JIM_ERR;
-#endif
+ return JimSetFileTimes(interp, Jim_String(argv[0]), us);
}
if (file_stat(interp, argv[0], &sb) != JIM_OK) {
return JIM_ERR;
}
- Jim_SetResultInt(interp, sb.st_mtime);
+ Jim_SetResultInt(interp, STAT_MTIME_US(sb));
return JIM_OK;
}
+#endif
static int file_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
@@ -765,6 +803,15 @@ static const jim_subcmd_type file_command_table[] = {
2,
/* Description: Get or set last modification time */
},
+#ifdef STAT_MTIME_US
+ { "mtimeus",
+ "name ?time?",
+ file_cmd_mtimeus,
+ 1,
+ 2,
+ /* Description: Get or set last modification time in microseconds */
+ },
+#endif
{ "copy",
"?-force? source dest",
file_cmd_copy,