]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
Use File Descriptor in Setting Stat on Output File 3479/head
authorW. Felix Handte <w@felixhandte.com>
Mon, 6 Feb 2023 16:05:47 +0000 (08:05 -0800)
committerW. Felix Handte <w@felixhandte.com>
Mon, 6 Feb 2023 22:02:31 +0000 (14:02 -0800)
Note that the `fd` is only valid while the file is still open. So we need to
move the setting calls to before we close the file. However! We cannot do so
with the `utime()` call (even though `futimens()` exists) because the follow-
ing `close()` call to the `fd` will reset the atime of the file. So it seems
the `utime()` call has to happen after the file is closed.

programs/fileio.c
programs/util.c
tests/cli-tests/file-stat/compress-file-to-file.sh.stderr.exact
tests/cli-tests/file-stat/decompress-file-to-file.sh.stderr.exact

index 9a8300cdd834209d049cacf3debc69a766344c87..75f2476774053f38aec05f61f5ac72948aa79fff 100644 (file)
@@ -1681,6 +1681,7 @@ static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx,
     int result;
     int transferStat = 0;
     FILE *dstFile;
+    int dstFd = -1;
 
     assert(AIO_ReadPool_getFile(ress.readCtx) != NULL);
     if (AIO_WritePool_getFile(ress.writeCtx) == NULL) {
@@ -1696,6 +1697,7 @@ static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx,
         DISPLAYLEVEL(6, "FIO_compressFilename_dstFile: opening dst: %s \n", dstFileName);
         dstFile = FIO_openDstFile(fCtx, prefs, srcFileName, dstFileName, dstFileInitialPermissions);
         if (dstFile==NULL) return 1;  /* could not open dstFileName */
+        dstFd = fileno(dstFile);
         AIO_WritePool_setFile(ress.writeCtx, dstFile);
         /* Must only be added after FIO_openDstFile() succeeds.
          * Otherwise we may delete the destination file if it already exists,
@@ -1709,14 +1711,20 @@ static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx,
     if (closeDstFile) {
         clearHandler();
 
+        if (transferStat) {
+            UTIL_setFDStat(dstFd, dstFileName, srcFileStat);
+        }
+
         DISPLAYLEVEL(6, "FIO_compressFilename_dstFile: closing dst: %s \n", dstFileName);
         if (AIO_WritePool_closeFile(ress.writeCtx)) { /* error closing file */
             DISPLAYLEVEL(1, "zstd: %s: %s \n", dstFileName, strerror(errno));
             result=1;
         }
+
         if (transferStat) {
-            UTIL_setFileStat(dstFileName, srcFileStat);
+            UTIL_utime(dstFileName, srcFileStat);
         }
+
         if ( (result != 0)  /* operation failure */
           && strcmp(dstFileName, stdoutmark)  /* special case : don't remove() stdout */
           ) {
@@ -2540,6 +2548,7 @@ static int FIO_decompressDstFile(FIO_ctx_t* const fCtx,
     int result;
     int releaseDstFile = 0;
     int transferStat = 0;
+    int dstFd = 0;
 
     if ((AIO_WritePool_getFile(ress.writeCtx) == NULL) && (prefs->testMode == 0)) {
         FILE *dstFile;
@@ -2555,6 +2564,7 @@ static int FIO_decompressDstFile(FIO_ctx_t* const fCtx,
 
         dstFile = FIO_openDstFile(fCtx, prefs, srcFileName, dstFileName, dstFilePermissions);
         if (dstFile==NULL) return 1;
+        dstFd = fileno(dstFile);
         AIO_WritePool_setFile(ress.writeCtx, dstFile);
 
         /* Must only be added after FIO_openDstFile() succeeds.
@@ -2568,13 +2578,18 @@ static int FIO_decompressDstFile(FIO_ctx_t* const fCtx,
 
     if (releaseDstFile) {
         clearHandler();
+
+        if (transferStat) {
+            UTIL_setFDStat(dstFd, dstFileName, srcFileStat);
+        }
+
         if (AIO_WritePool_closeFile(ress.writeCtx)) {
             DISPLAYLEVEL(1, "zstd: %s: %s \n", dstFileName, strerror(errno));
             result = 1;
         }
 
         if (transferStat) {
-            UTIL_setFileStat(dstFileName, srcFileStat);
+            UTIL_utime(dstFileName, srcFileStat);
         }
 
         if ( (result != 0)  /* operation failure */
index a3f5564afa0de72ea4fdacfe6a18d6894c58898a..c9031e91d35a9cba72e9a3b5e2d6ecc3f84a04ad 100644 (file)
@@ -295,9 +295,6 @@ int UTIL_setFDStat(const int fd, const char *filename, const stat_t *statbuf)
         return -1;
     }
 
-    /* set access and modification times */
-    res += UTIL_utime(filename, statbuf);
-
     /* Mimic gzip's behavior:
      *
      * "Change the group first, then the permissions, then the owner.
index 913a99e1ed61847fd5c07adb4b29a66cb6fb8818..32d248ee50bf57a99ca2189b28322a230fb601ad 100644 (file)
@@ -30,13 +30,13 @@ Trace:FileStat: > UTIL_getFileSize(file)
 Trace:FileStat:  > UTIL_stat(-1, file)
 Trace:FileStat:  < 1
 Trace:FileStat: < 65537
-Trace:FileStat: > UTIL_setFileStat(-1, file.zst)
-Trace:FileStat:  > UTIL_stat(-1, file.zst)
+Trace:FileStat: > UTIL_setFileStat(4, file.zst)
+Trace:FileStat:  > UTIL_stat(4, file.zst)
 Trace:FileStat:  < 1
-Trace:FileStat:  > UTIL_utime(file.zst)
-Trace:FileStat:  < 0
 Trace:FileStat:  > UTIL_chmod(file.zst, 0642)
-Trace:FileStat:   > chmod
+Trace:FileStat:   > fchmod
 Trace:FileStat:   < 0
 Trace:FileStat:  < 0
 Trace:FileStat: < 0
+Trace:FileStat: > UTIL_utime(file.zst)
+Trace:FileStat: < 0
index 1d872fb7dc77244b01b9961599051de4af3c211e..ad3a0deb868664bbd90c22e6c267926a1ee9a294 100644 (file)
@@ -26,13 +26,13 @@ Trace:FileStat: > UTIL_isRegularFile(file)
 Trace:FileStat:  > UTIL_stat(-1, file)
 Trace:FileStat:  < 1
 Trace:FileStat: < 1
-Trace:FileStat: > UTIL_setFileStat(-1, file)
-Trace:FileStat:  > UTIL_stat(-1, file)
+Trace:FileStat: > UTIL_setFileStat(4, file)
+Trace:FileStat:  > UTIL_stat(4, file)
 Trace:FileStat:  < 1
-Trace:FileStat:  > UTIL_utime(file)
-Trace:FileStat:  < 0
 Trace:FileStat:  > UTIL_chmod(file, 0642)
-Trace:FileStat:   > chmod
+Trace:FileStat:   > fchmod
 Trace:FileStat:   < 0
 Trace:FileStat:  < 0
 Trace:FileStat: < 0
+Trace:FileStat: > UTIL_utime(file)
+Trace:FileStat: < 0