From 04d7a5fcb45950be3e0b86c91c7852bc92e11c49 Mon Sep 17 00:00:00 2001
From: Andrey Gursky <andrey.gursky@e-mail.ua>
Date: Sat, 29 Oct 2016 02:31:40 +0200
Subject: [PATCH] Ticket #3575: generate timestamps with nanosecond precision
for touch
Sample fish/utime helper content:
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"
else
echo "### 500"
fi
---
src/vfs/fish/fish.c | 44 ++++++++++++++++++++++++++------------------
1 file changed, 26 insertions(+), 18 deletions(-)
diff --git a/src/vfs/fish/fish.c b/src/vfs/fish/fish.c
index e04c877..dab1d90 100644
a
|
b
|
fish_chown (const vfs_path_t * vpath, uid_t owner, gid_t group) |
1323 | 1323 | |
1324 | 1324 | /* --------------------------------------------------------------------------------------------- */ |
1325 | 1325 | |
1326 | | static time_t |
1327 | | fish_get_atime (mc_timesbuf_t * times) |
| 1326 | static void |
| 1327 | fish_get_atime (mc_timesbuf_t * times, time_t * sec, long * nsec) |
1328 | 1328 | { |
1329 | | time_t ret; |
1330 | | |
1331 | 1329 | #ifdef HAVE_UTIMENSAT |
1332 | | ret = (*times)[0].tv_sec; |
| 1330 | *sec = (*times)[0].tv_sec; |
| 1331 | *nsec = (*times)[0].tv_nsec; |
1333 | 1332 | #else |
1334 | | ret = times->actime; |
| 1333 | *sec = times->actime; |
| 1334 | *nsec = 0; |
1335 | 1335 | #endif |
1336 | | return ret; |
1337 | 1336 | } |
1338 | 1337 | |
1339 | 1338 | /* --------------------------------------------------------------------------------------------- */ |
1340 | 1339 | |
1341 | | static time_t |
1342 | | fish_get_mtime (mc_timesbuf_t * times) |
| 1340 | static void |
| 1341 | fish_get_mtime (mc_timesbuf_t * times, time_t * sec, long * nsec) |
1343 | 1342 | { |
1344 | | time_t ret; |
1345 | | |
1346 | 1343 | #ifdef HAVE_UTIMENSAT |
1347 | | ret = (*times)[1].tv_sec; |
| 1344 | *sec = (*times)[1].tv_sec; |
| 1345 | *nsec = (*times)[1].tv_nsec; |
1348 | 1346 | #else |
1349 | | ret = times->modtime; |
| 1347 | *sec = times->modtime; |
| 1348 | *nsec = 0; |
1350 | 1349 | #endif |
1351 | | return ret; |
1352 | 1350 | } |
1353 | 1351 | |
1354 | 1352 | /* --------------------------------------------------------------------------------------------- */ |
… |
… |
fish_utime (const vfs_path_t * vpath, mc_timesbuf_t * times) |
1358 | 1356 | { |
1359 | 1357 | gchar *shell_commands = NULL; |
1360 | 1358 | char utcatime[16], utcmtime[16]; |
| 1359 | char utcatime_w_nsec[30], utcmtime_w_nsec[30]; |
1361 | 1360 | time_t atime, mtime; |
| 1361 | long atime_nsec, mtime_nsec; |
1362 | 1362 | struct tm *gmt; |
1363 | 1363 | char buf[BUF_LARGE]; |
1364 | 1364 | const char *crpath; |
… |
… |
fish_utime (const vfs_path_t * vpath, mc_timesbuf_t * times) |
1373 | 1373 | return -1; |
1374 | 1374 | rpath = strutils_shell_escape (crpath); |
1375 | 1375 | |
1376 | | atime = fish_get_atime (times); |
| 1376 | fish_get_atime (times, &atime, &atime_nsec); |
1377 | 1377 | gmt = gmtime (&atime); |
1378 | 1378 | g_snprintf (utcatime, sizeof (utcatime), "%04d%02d%02d%02d%02d.%02d", |
1379 | 1379 | gmt->tm_year + 1900, gmt->tm_mon + 1, gmt->tm_mday, |
1380 | 1380 | gmt->tm_hour, gmt->tm_min, gmt->tm_sec); |
| 1381 | g_snprintf (utcatime_w_nsec, sizeof (utcatime_w_nsec), "%04d-%02d-%02d %02d:%02d:%02d.%09ld", |
| 1382 | gmt->tm_year + 1900, gmt->tm_mon + 1, gmt->tm_mday, |
| 1383 | gmt->tm_hour, gmt->tm_min, gmt->tm_sec, atime_nsec); |
1381 | 1384 | |
1382 | | mtime = fish_get_mtime (times); |
| 1385 | fish_get_mtime (times, &mtime, &mtime_nsec); |
1383 | 1386 | gmt = gmtime (&mtime); |
1384 | 1387 | g_snprintf (utcmtime, sizeof (utcmtime), "%04d%02d%02d%02d%02d.%02d", |
1385 | 1388 | gmt->tm_year + 1900, gmt->tm_mon + 1, gmt->tm_mday, |
1386 | 1389 | gmt->tm_hour, gmt->tm_min, gmt->tm_sec); |
| 1390 | g_snprintf (utcmtime_w_nsec, sizeof (utcmtime_w_nsec), "%04d-%02d-%02d %02d:%02d:%02d.%09ld", |
| 1391 | gmt->tm_year + 1900, gmt->tm_mon + 1, gmt->tm_mday, |
| 1392 | gmt->tm_hour, gmt->tm_min, gmt->tm_sec, mtime_nsec); |
1387 | 1393 | |
1388 | 1394 | shell_commands = |
1389 | 1395 | g_strconcat (SUP->scr_env, "FISH_FILENAME=%s FISH_FILEATIME=%ld FISH_FILEMTIME=%ld ", |
1390 | | "FISH_TOUCHATIME=%s FISH_TOUCHMTIME=%s;\n", SUP->scr_utime, (char *) NULL); |
| 1396 | "FISH_TOUCHATIME=%s FISH_TOUCHMTIME=%s ", |
| 1397 | "FISH_TOUCHATIME_W_NSEC=\"%s\" FISH_TOUCHMTIME_W_NSEC=\"%s\";\n", |
| 1398 | SUP->scr_utime, (char *) NULL); |
1391 | 1399 | g_snprintf (buf, sizeof (buf), shell_commands, rpath, (long) atime, (long) mtime, |
1392 | | utcatime, utcmtime); |
| 1400 | utcatime, utcmtime, utcatime_w_nsec, utcmtime_w_nsec); |
1393 | 1401 | g_free (shell_commands); |
1394 | 1402 | g_free (rpath); |
1395 | 1403 | return fish_send_command (path_element->class, super, buf, OPT_FLUSH); |