diff --git a/programs/fileio.c b/programs/fileio.c index 0633d39d..7d58a11e 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -509,7 +509,7 @@ static int FIO_remove(const char* path) #if defined(_WIN32) || defined(WIN32) /* windows doesn't allow remove read-only files, * so try to make it writable first */ - UTIL_chmod(path, _S_IWRITE); + UTIL_chmod(path, NULL, _S_IWRITE); #endif return remove(path); } @@ -619,7 +619,7 @@ FIO_openDstFile(FIO_prefs_t* const prefs, && strcmp (srcFileName, stdinmark) && strcmp(dstFileName, nulmark) ) { /* reduce rights on newly created dst file while compression is ongoing */ - UTIL_chmod(dstFileName, 00600); + UTIL_chmod(dstFileName, NULL, 00600); } return f; } diff --git a/programs/util.c b/programs/util.c index 69b93b8d..fd4d7a60 100644 --- a/programs/util.c +++ b/programs/util.c @@ -142,9 +142,14 @@ int UTIL_statDir(const char* infilename, stat_t *statbuf) } /* like chmod, but avoid changing permission of /dev/null */ -int UTIL_chmod(char const* filename, mode_t permissions) +int UTIL_chmod(char const* filename, const stat_t* statbuf, mode_t permissions) { - if (!strcmp(filename, "/dev/null")) return 0; /* pretend success, but don't change anything */ + stat_t localStatBuf; + if (statbuf == NULL) { + if (!UTIL_stat(filename, &localStatBuf)) return 0; + statbuf = &localStatBuf; + } + if (!UTIL_isRegularFileStat(statbuf)) return 0; /* pretend success, but don't change anything */ return chmod(filename, permissions); } @@ -180,7 +185,7 @@ int UTIL_setFileStat(const char *filename, const stat_t *statbuf) res += chown(filename, statbuf->st_uid, statbuf->st_gid); /* Copy ownership */ #endif - res += UTIL_chmod(filename, statbuf->st_mode & 07777); /* Copy file permissions */ + res += UTIL_chmod(filename, NULL, statbuf->st_mode & 07777); /* Copy file permissions */ errno = 0; return -res; /* number of errors is returned */ diff --git a/programs/util.h b/programs/util.h index 0a3be31c..f75bca04 100644 --- a/programs/util.h +++ b/programs/util.h @@ -140,7 +140,12 @@ U64 UTIL_getFileSize(const char* infilename); U64 UTIL_getFileSizeStat(const stat_t* statbuf); U64 UTIL_getTotalFileSize(const char* const * fileNamesTable, unsigned nbFiles); int UTIL_setFileStat(const char* filename, const stat_t* statbuf); -int UTIL_chmod(char const* filename, mode_t permissions); /*< like chmod, but avoid changing permission of /dev/null */ +/** + * Like chmod, but only modifies regular files. Provided statbuf may be NULL, + * in which case this function will stat() the file internally, in order to + * check that it should be modified. + */ +int UTIL_chmod(char const* filename, const stat_t* statbuf, mode_t permissions); int UTIL_compareStr(const void *p1, const void *p2); const char* UTIL_getFileExtension(const char* infilename); void UTIL_mirrorSourceFilesDirectories(const char** fileNamesTable, unsigned int nbFiles, const char *outDirName);