Merge pull request #2742 from felixhandte/set-mtime

Set mtime on Output Files
This commit is contained in:
Felix Handte 2021-08-04 16:44:46 -04:00 committed by GitHub
commit ae131282f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 61 additions and 19 deletions

View File

@ -1647,6 +1647,7 @@ static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx,
int closeDstFile = 0;
int result;
stat_t statbuf;
int transferMTime = 0;
assert(ress.srcFile != NULL);
if (ress.dstFile == NULL) {
int dstFilePermissions = DEFAULT_FILE_PERMISSIONS;
@ -1654,6 +1655,7 @@ static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx,
&& UTIL_stat(srcFileName, &statbuf)
&& UTIL_isRegularFileStat(&statbuf) ) {
dstFilePermissions = statbuf.st_mode;
transferMTime = 1;
}
closeDstFile = 1;
@ -1680,6 +1682,9 @@ static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx,
DISPLAYLEVEL(1, "zstd: %s: %s \n", dstFileName, strerror(errno));
result=1;
}
if (transferMTime) {
UTIL_utime(dstFileName, &statbuf);
}
if ( (result != 0) /* operation failure */
&& strcmp(dstFileName, stdoutmark) /* special case : don't remove() stdout */
) {
@ -2553,6 +2558,7 @@ static int FIO_decompressDstFile(FIO_ctx_t* const fCtx,
int result;
stat_t statbuf;
int releaseDstFile = 0;
int transferMTime = 0;
if ((ress.dstFile == NULL) && (prefs->testMode==0)) {
int dstFilePermissions = DEFAULT_FILE_PERMISSIONS;
@ -2560,6 +2566,7 @@ static int FIO_decompressDstFile(FIO_ctx_t* const fCtx,
&& UTIL_stat(srcFileName, &statbuf)
&& UTIL_isRegularFileStat(&statbuf) ) {
dstFilePermissions = statbuf.st_mode;
transferMTime = 1;
}
releaseDstFile = 1;
@ -2585,6 +2592,10 @@ static int FIO_decompressDstFile(FIO_ctx_t* const fCtx,
result = 1;
}
if (transferMTime) {
UTIL_utime(dstFileName, &statbuf);
}
if ( (result != 0) /* operation failure */
&& strcmp(dstFileName, stdoutmark) /* special case : don't remove() stdout */
) {

View File

@ -159,6 +159,29 @@ int UTIL_chmod(char const* filename, const stat_t* statbuf, mode_t permissions)
return chmod(filename, permissions);
}
/* set access and modification times */
int UTIL_utime(const char* filename, const stat_t *statbuf)
{
int ret;
/* We check that st_mtime is a macro here in order to give us confidence
* that struct stat has a struct timespec st_mtim member. We need this
* check because there are some platforms that claim to be POSIX 2008
* compliant but which do not have st_mtim... */
#if (PLATFORM_POSIX_VERSION >= 200809L) && defined(st_mtime)
/* (atime, mtime) */
struct timespec timebuf[2] = { {0, UTIME_NOW} };
timebuf[1] = statbuf->st_mtim;
ret = utimensat(AT_FDCWD, filename, timebuf, 0);
#else
struct utimbuf timebuf;
timebuf.actime = time(NULL);
timebuf.modtime = statbuf->st_mtime;
ret = utime(filename, &timebuf);
#endif
errno = 0;
return ret;
}
int UTIL_setFileStat(const char *filename, const stat_t *statbuf)
{
int res = 0;
@ -168,25 +191,7 @@ int UTIL_setFileStat(const char *filename, const stat_t *statbuf)
return -1;
/* set access and modification times */
/* We check that st_mtime is a macro here in order to give us confidence
* that struct stat has a struct timespec st_mtim member. We need this
* check because there are some platforms that claim to be POSIX 2008
* compliant but which do not have st_mtim... */
#if (PLATFORM_POSIX_VERSION >= 200809L) && defined(st_mtime)
{
/* (atime, mtime) */
struct timespec timebuf[2] = { {0, UTIME_NOW} };
timebuf[1] = statbuf->st_mtim;
res += utimensat(AT_FDCWD, filename, timebuf, 0);
}
#else
{
struct utimbuf timebuf;
timebuf.actime = time(NULL);
timebuf.modtime = statbuf->st_mtime;
res += utime(filename, &timebuf);
}
#endif
res += UTIL_utime(filename, statbuf);
#if !defined(_WIN32)
res += chown(filename, statbuf->st_uid, statbuf->st_gid); /* Copy ownership */

View File

@ -136,6 +136,14 @@ int UTIL_stat(const char* filename, stat_t* statbuf);
*/
int UTIL_setFileStat(const char* filename, const stat_t* statbuf);
/**
* Set atime to now and mtime to the st_mtim in statbuf.
*
* Directly wraps utime() or utimensat(). Returns -1 on error.
* Does not validate filename is valid.
*/
int UTIL_utime(const char* filename, const stat_t *statbuf);
/*
* These helpers operate on a pre-populated stat_t, i.e., the result of
* calling one of the above functions.

View File

@ -124,6 +124,13 @@ case "$UNAME" in
Darwin | FreeBSD | OpenBSD | NetBSD) MTIME="stat -f %m" ;;
esac
assertSameMTime() {
MT1=$($MTIME "$1")
MT2=$($MTIME "$2")
echo MTIME $MT1 $MT2
[ "$MT1" = "$MT2" ] || die "mtime on $1 doesn't match mtime on $2 ($MT1 != $MT2)"
}
GET_PERMS="stat -c %a"
case "$UNAME" in
Darwin | FreeBSD | OpenBSD | NetBSD) GET_PERMS="stat -f %Lp" ;;
@ -588,6 +595,17 @@ if [ -n "$READFROMBLOCKDEVICE" ] ; then
rm -f tmp.img tmp.img.zst tmp.img.copy
fi
println "\n===> zstd created file timestamp tests"
datagen > tmp
touch -m -t 200001010000.00 tmp
println "test : copy mtime in file -> file compression "
zstd -f tmp -o tmp.zst
assertSameMTime tmp tmp.zst
println "test : copy mtime in file -> file decompression "
zstd -f -d tmp.zst -o tmp.out
assertSameMTime tmp.zst tmp.out
rm -f tmp
println "\n===> compress multiple files into an output directory, --output-dir-flat"
println henlo > tmp1
mkdir tmpInputTestDir