FISH VFS: generate timestamps with nanosecond precision for touch.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
Andrey Gursky 2016-10-29 02:31:40 +02:00 committed by Andrew Borodin
parent 53a1d52ed9
commit 0075944f1e
3 changed files with 42 additions and 25 deletions

View File

@ -1323,32 +1323,30 @@ fish_chown (const vfs_path_t * vpath, uid_t owner, gid_t group)
/* --------------------------------------------------------------------------------------------- */
static time_t
fish_get_atime (mc_timesbuf_t * times)
static void
fish_get_atime (mc_timesbuf_t * times, time_t * sec, long *nsec)
{
time_t ret;
#ifdef HAVE_UTIMENSAT
ret = (*times)[0].tv_sec;
*sec = (*times)[0].tv_sec;
*nsec = (*times)[0].tv_nsec;
#else
ret = times->actime;
*sec = times->actime;
*nsec = 0;
#endif
return ret;
}
/* --------------------------------------------------------------------------------------------- */
static time_t
fish_get_mtime (mc_timesbuf_t * times)
static void
fish_get_mtime (mc_timesbuf_t * times, time_t * sec, long *nsec)
{
time_t ret;
#ifdef HAVE_UTIMENSAT
ret = (*times)[1].tv_sec;
*sec = (*times)[1].tv_sec;
*nsec = (*times)[1].tv_nsec;
#else
ret = times->modtime;
*sec = times->modtime;
*nsec = 0;
#endif
return ret;
}
/* --------------------------------------------------------------------------------------------- */
@ -1358,7 +1356,9 @@ fish_utime (const vfs_path_t * vpath, mc_timesbuf_t * times)
{
gchar *shell_commands = NULL;
char utcatime[16], utcmtime[16];
char utcatime_w_nsec[30], utcmtime_w_nsec[30];
time_t atime, mtime;
long atime_nsec, mtime_nsec;
struct tm *gmt;
char *cmd;
const char *crpath;
@ -1374,22 +1374,32 @@ fish_utime (const vfs_path_t * vpath, mc_timesbuf_t * times)
return -1;
rpath = strutils_shell_escape (crpath);
atime = fish_get_atime (times);
fish_get_atime (times, &atime, &atime_nsec);
gmt = gmtime (&atime);
g_snprintf (utcatime, sizeof (utcatime), "%04d%02d%02d%02d%02d.%02d",
gmt->tm_year + 1900, gmt->tm_mon + 1, gmt->tm_mday,
gmt->tm_hour, gmt->tm_min, gmt->tm_sec);
g_snprintf (utcatime_w_nsec, sizeof (utcatime_w_nsec), "%04d-%02d-%02d %02d:%02d:%02d.%09ld",
gmt->tm_year + 1900, gmt->tm_mon + 1, gmt->tm_mday,
gmt->tm_hour, gmt->tm_min, gmt->tm_sec, atime_nsec);
mtime = fish_get_mtime (times);
fish_get_mtime (times, &mtime, &mtime_nsec);
gmt = gmtime (&mtime);
g_snprintf (utcmtime, sizeof (utcmtime), "%04d%02d%02d%02d%02d.%02d",
gmt->tm_year + 1900, gmt->tm_mon + 1, gmt->tm_mday,
gmt->tm_hour, gmt->tm_min, gmt->tm_sec);
g_snprintf (utcmtime_w_nsec, sizeof (utcmtime_w_nsec), "%04d-%02d-%02d %02d:%02d:%02d.%09ld",
gmt->tm_year + 1900, gmt->tm_mon + 1, gmt->tm_mday,
gmt->tm_hour, gmt->tm_min, gmt->tm_sec, mtime_nsec);
shell_commands =
g_strconcat (SUP->scr_env, "FISH_FILENAME=%s FISH_FILEATIME=%ld FISH_FILEMTIME=%ld ",
"FISH_TOUCHATIME=%s FISH_TOUCHMTIME=%s;\n", SUP->scr_utime, (char *) NULL);
cmd = g_strdup_printf (shell_commands, rpath, (long) atime, (long) mtime, utcatime, utcmtime);
"FISH_TOUCHATIME=%s FISH_TOUCHMTIME=%s ",
"FISH_TOUCHATIME_W_NSEC=\"%s\" FISH_TOUCHMTIME_W_NSEC=\"%s\";\n",
SUP->scr_utime, (char *) NULL);
cmd =
g_strdup_printf (shell_commands, rpath, (long) atime, (long) mtime, utcatime, utcmtime,
utcatime_w_nsec, utcmtime_w_nsec);
g_free (shell_commands);
g_free (rpath);
ret = fish_send_command (path_element->class, super, cmd, OPT_FLUSH);

View File

@ -76,17 +76,21 @@
/* default 'utime' script */
#define FISH_UTIME_DEF_CONTENT "" \
"#UTIME $FISH_FILEATIME $FISH_FILEMTIME $FISH_FILENAME\n" \
"if [ -n \"$FISH_HAVE_PERL\" ] && \\\n" \
" perl -e 'utime '$FISH_FILEATIME','$FISH_FILEMTIME',@ARGV;' \"/${FISH_FILENAME}\" 2>/dev/null; then\n" \
"#UTIME \"$FISH_TOUCHATIME_W_NSEC\" \"$FISH_TOUCHMTIME_W_NSEC\" $FISH_FILENAME\n" \
"if TZ=UTC touch -m -d \"$FISH_TOUCHMTIME_W_NSEC\" \"/${FISH_FILENAME}\" 2>/dev/null && \\\n" \
" TZ=UTC touch -a -d \"$FISH_TOUCHATIME_W_NSEC\" \"/${FISH_FILENAME}\" 2>/dev/null; then\n" \
" echo \"### 000\"\n" \
"elif TZ=UTC touch -m -t $FISH_TOUCHMTIME \"/${FISH_FILENAME}\" 2>/dev/null && \\\n" \
" TZ=UTC touch -a -t $FISH_TOUCHATIME \"/${FISH_FILENAME}\" 2>/dev/null; then\n" \
" echo \"### 000\"\n" \
"elif [ -n \"$FISH_HAVE_PERL\" ] && \\\n" \
" perl -e 'utime '$FISH_FILEATIME','$FISH_FILEMTIME',@ARGV;' \"/${FISH_FILENAME}\" 2>/dev/null; then\n" \
" echo \"### 000\"\n" \
"else\n" \
" echo \"### 500\"\n" \
"fi\n"
/* default 'rmdir' script */
#define FISH_RMDIR_DEF_CONTENT "" \
"#RMD $FISH_FILENAME\n" \

View File

@ -1,10 +1,13 @@
#UTIME $FISH_FILEATIME $FISH_FILEMTIME $FISH_FILENAME
if [ -n "$FISH_HAVE_PERL" ] &&
perl -e 'utime '$FISH_FILEATIME','$FISH_FILEMTIME',@ARGV;' "/${FISH_FILENAME}" 2>/dev/null; then
#UTIME "$FISH_TOUCHATIME_W_NSEC" "$FISH_TOUCHMTIME_W_NSEC" "$FISH_FILENAME"
if TZ=UTC touch -m -d "$FISH_TOUCHMTIME_W_NSEC" "/${FISH_FILENAME}" 2>/dev/null && \
TZ=UTC touch -a -d "$FISH_TOUCHATIME_W_NSEC" "/${FISH_FILENAME}" 2>/dev/null; then
echo "### 000"
elif TZ=UTC touch -m -t $FISH_TOUCHMTIME "/${FISH_FILENAME}" 2>/dev/null &&
elif TZ=UTC touch -m -t $FISH_TOUCHMTIME "/${FISH_FILENAME}" 2>/dev/null && \
TZ=UTC touch -a -t $FISH_TOUCHATIME "/${FISH_FILENAME}" 2>/dev/null; then
echo "### 000"
elif [ -n "$FISH_HAVE_PERL" ] &&
perl -e 'utime '$FISH_FILEATIME','$FISH_FILEMTIME',@ARGV;' "/${FISH_FILENAME}" 2>/dev/null; then
echo "### 000"
else
echo "### 500"
fi