]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
set permissions, access and modification times
authorPrzemyslaw Skibinski <inikep@gmail.com>
Wed, 2 Nov 2016 13:08:07 +0000 (14:08 +0100)
committerPrzemyslaw Skibinski <inikep@gmail.com>
Wed, 2 Nov 2016 13:08:07 +0000 (14:08 +0100)
programs/fileio.c
programs/util.h

index 44b41221c2d2a01de3bcdf4ae522e57fa72041cb..3d31a07c6f7479b5d008b75c462ae4db3c10d1f4 100644 (file)
@@ -388,17 +388,18 @@ static int FIO_compressFilename_dstFile(cRess_t ress,
                                         const char* dstFileName, const char* srcFileName)
 {
     int result;
-    time_t modtime = 0;
+    stat_t statbuf;
+    int stat_result = 0;
 
     ress.dstFile = FIO_openDstFile(dstFileName);
     if (ress.dstFile==NULL) return 1;  /* could not open dstFileName */
 
-    if (strcmp (srcFileName, stdinmark)) modtime = UTIL_getModificationTime(srcFileName);
+    if (strcmp (srcFileName, stdinmark) && UTIL_getFileStat(srcFileName, &statbuf)) stat_result = 1;
     result = FIO_compressFilename_srcFile(ress, dstFileName, srcFileName);
 
     if (fclose(ress.dstFile)) { DISPLAYLEVEL(1, "zstd: %s: %s \n", dstFileName, strerror(errno)); result=1; }  /* error closing dstFile */
     if (result!=0) { if (remove(dstFileName)) EXM_THROW(1, "zstd: %s: %s", dstFileName, strerror(errno)); }  /* remove operation artefact */
-    else if (strcmp (dstFileName, stdoutmark)) UTIL_setModificationTime(dstFileName, modtime);
+    else if (strcmp (dstFileName, stdoutmark) && stat_result) UTIL_setFileStat(dstFileName, &statbuf);
     return result;
 }
 
@@ -723,12 +724,13 @@ static int FIO_decompressDstFile(dRess_t ress,
                                       const char* dstFileName, const char* srcFileName)
 {
     int result;
-    time_t modtime = 0;
+    stat_t statbuf;
+    int stat_result = 0;
 
     ress.dstFile = FIO_openDstFile(dstFileName);
     if (ress.dstFile==0) return 1;
 
-    if (strcmp (srcFileName, stdinmark)) modtime = UTIL_getModificationTime(srcFileName);
+    if (strcmp (srcFileName, stdinmark) && UTIL_getFileStat(srcFileName, &statbuf)) stat_result = 1;
     result = FIO_decompressSrcFile(ress, srcFileName);
 
     if (fclose(ress.dstFile)) EXM_THROW(38, "Write error : cannot properly close %s", dstFileName);    
@@ -737,7 +739,7 @@ static int FIO_decompressDstFile(dRess_t ress,
        && strcmp(dstFileName, nulmark)  /* special case : don't remove() /dev/null (#316) */
        && remove(dstFileName) )
         result=1;   /* don't do anything special if remove() fails */
-    else if (strcmp (dstFileName, stdoutmark)) UTIL_setModificationTime(dstFileName, modtime);
+    else if (strcmp (dstFileName, stdoutmark) && stat_result) UTIL_setFileStat(dstFileName, &statbuf);
     return result;
 }
 
index 1bbe2a736de68efd98a6b264fc81a756724090e0..7d503d9df5091a2809b2ea3cde268f924af4a38c 100644 (file)
@@ -50,6 +50,7 @@ extern "C" {
 #include <sys/stat.h>   /* stat */
 #include <utime.h>      /* utime */
 #include <time.h>       /* time */
+#include <unistd.h>     /* chown, stat */
 #include "mem.h"        /* U32, U64 */
 
 
@@ -144,33 +145,44 @@ UTIL_STATIC void UTIL_waitForNextTick(UTIL_time_t ticksPerSecond)
 /*-****************************************
 *  File functions
 ******************************************/
-UTIL_STATIC int UTIL_setModificationTime(const char *filename, time_t modtime)
+#if defined(_MSC_VER)
+    typedef struct _stat64 stat_t;
+#else
+    typedef struct stat stat_t;
+#endif
+
+
+UTIL_STATIC int UTIL_setFileStat(const char *filename, stat_t *statbuf)
 {
-    struct utimbuf  timebuf;
+    int res = 0;
+    struct utimbuf timebuf;
+
+#if !defined(_WIN32)
+    res += chown(filename, statbuf->st_uid, statbuf->st_gid);  /* Copy ownership */
+#endif
 
-    if (modtime == 0) return -1;
+    res += chmod(filename, statbuf->st_mode & 07777);  /* Copy file permissions */
 
     timebuf.actime  = time(NULL);
-    timebuf.modtime = modtime;
+    timebuf.modtime = statbuf->st_mtime;
+    res += utime(filename, &timebuf);  /* set access and modification times */
 
-    /* On success, zero is returned. On error, -1 is returned, and errno is set appropriately. */
-    return utime(filename, &timebuf); 
+    errno = 0;
+    return -res; /* number of errors is returned */
 }
 
 
-UTIL_STATIC time_t UTIL_getModificationTime(const char* infilename)
+UTIL_STATIC int UTIL_getFileStat(const char* infilename, stat_t *statbuf)
 {
     int r;
 #if defined(_MSC_VER)
-    struct _stat64 statbuf;
-    r = _stat64(infilename, &statbuf);
-    if (r || !(statbuf.st_mode & S_IFREG)) return 0;   /* No good... */
+    r = _stat64(infilename, statbuf);
+    if (r || !(statbuf->st_mode & S_IFREG)) return 0;   /* No good... */
 #else
-    struct stat statbuf;
-    r = stat(infilename, &statbuf);
-    if (r || !S_ISREG(statbuf.st_mode)) return 0;   /* No good... */
+    r = stat(infilename, statbuf);
+    if (r || !S_ISREG(statbuf->st_mode)) return 0;   /* No good... */
 #endif
-    return statbuf.st_mtime;
+    return 1;
 }