10c16b537SWarner Losh /* 2*37f1f268SConrad Meyer * Copyright (c) 2016-2020, Przemyslaw Skibinski, Yann Collet, Facebook, Inc. 30c16b537SWarner Losh * All rights reserved. 40c16b537SWarner Losh * 50c16b537SWarner Losh * This source code is licensed under both the BSD-style license (found in the 60c16b537SWarner Losh * LICENSE file in the root directory of this source tree) and the GPLv2 (found 70c16b537SWarner Losh * in the COPYING file in the root directory of this source tree). 80c16b537SWarner Losh * You may select, at your option, one of the above-listed licenses. 90c16b537SWarner Losh */ 100c16b537SWarner Losh 110c16b537SWarner Losh #ifndef UTIL_H_MODULE 120c16b537SWarner Losh #define UTIL_H_MODULE 130c16b537SWarner Losh 140c16b537SWarner Losh #if defined (__cplusplus) 150c16b537SWarner Losh extern "C" { 160c16b537SWarner Losh #endif 170c16b537SWarner Losh 180c16b537SWarner Losh 190c16b537SWarner Losh /*-**************************************** 200c16b537SWarner Losh * Dependencies 210c16b537SWarner Losh ******************************************/ 220f743729SConrad Meyer #include "platform.h" /* PLATFORM_POSIX_VERSION, ZSTD_NANOSLEEP_SUPPORT, ZSTD_SETPRIORITY_SUPPORT */ 230c16b537SWarner Losh #include <stddef.h> /* size_t, ptrdiff_t */ 240c16b537SWarner Losh #include <sys/types.h> /* stat, utime */ 250f743729SConrad Meyer #include <sys/stat.h> /* stat, chmod */ 26*37f1f268SConrad Meyer #include "../lib/common/mem.h" /* U64 */ 27*37f1f268SConrad Meyer 280c16b537SWarner Losh 29a0483764SConrad Meyer /*-************************************************************ 300f743729SConrad Meyer * Avoid fseek()'s 2GiB barrier with MSVC, macOS, *BSD, MinGW 310c16b537SWarner Losh ***************************************************************/ 320c16b537SWarner Losh #if defined(_MSC_VER) && (_MSC_VER >= 1400) 330c16b537SWarner Losh # define UTIL_fseek _fseeki64 340c16b537SWarner Losh #elif !defined(__64BIT__) && (PLATFORM_POSIX_VERSION >= 200112L) /* No point defining Large file for 64 bit */ 350c16b537SWarner Losh # define UTIL_fseek fseeko 360c16b537SWarner Losh #elif defined(__MINGW32__) && defined(__MSVCRT__) && !defined(__STRICT_ANSI__) && !defined(__NO_MINGW_LFS) 370c16b537SWarner Losh # define UTIL_fseek fseeko64 380c16b537SWarner Losh #else 390c16b537SWarner Losh # define UTIL_fseek fseek 400c16b537SWarner Losh #endif 410c16b537SWarner Losh 420c16b537SWarner Losh 430f743729SConrad Meyer /*-************************************************* 440f743729SConrad Meyer * Sleep & priority functions: Windows - Posix - others 450f743729SConrad Meyer ***************************************************/ 460c16b537SWarner Losh #if defined(_WIN32) 470c16b537SWarner Losh # include <windows.h> 480c16b537SWarner Losh # define SET_REALTIME_PRIORITY SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS) 490c16b537SWarner Losh # define UTIL_sleep(s) Sleep(1000*s) 500c16b537SWarner Losh # define UTIL_sleepMilli(milli) Sleep(milli) 510f743729SConrad Meyer 520f743729SConrad Meyer #elif PLATFORM_POSIX_VERSION > 0 /* Unix-like operating system */ 530f743729SConrad Meyer # include <unistd.h> /* sleep */ 540c16b537SWarner Losh # define UTIL_sleep(s) sleep(s) 550f743729SConrad Meyer # if ZSTD_NANOSLEEP_SUPPORT /* necessarily defined in platform.h */ 560c16b537SWarner Losh # define UTIL_sleepMilli(milli) { struct timespec t; t.tv_sec=0; t.tv_nsec=milli*1000000ULL; nanosleep(&t, NULL); } 570c16b537SWarner Losh # else 580c16b537SWarner Losh # define UTIL_sleepMilli(milli) /* disabled */ 590c16b537SWarner Losh # endif 600f743729SConrad Meyer # if ZSTD_SETPRIORITY_SUPPORT 610f743729SConrad Meyer # include <sys/resource.h> /* setpriority */ 620f743729SConrad Meyer # define SET_REALTIME_PRIORITY setpriority(PRIO_PROCESS, 0, -20) 630c16b537SWarner Losh # else 640c16b537SWarner Losh # define SET_REALTIME_PRIORITY /* disabled */ 650f743729SConrad Meyer # endif 660f743729SConrad Meyer 670f743729SConrad Meyer #else /* unknown non-unix operating systen */ 680c16b537SWarner Losh # define UTIL_sleep(s) /* disabled */ 690c16b537SWarner Losh # define UTIL_sleepMilli(milli) /* disabled */ 700f743729SConrad Meyer # define SET_REALTIME_PRIORITY /* disabled */ 710c16b537SWarner Losh #endif 720c16b537SWarner Losh 730c16b537SWarner Losh 740c16b537SWarner Losh /*-**************************************** 750c16b537SWarner Losh * Compiler specifics 760c16b537SWarner Losh ******************************************/ 770c16b537SWarner Losh #if defined(__INTEL_COMPILER) 780c16b537SWarner Losh # pragma warning(disable : 177) /* disable: message #177: function was declared but never referenced, useful with UTIL_STATIC */ 790c16b537SWarner Losh #endif 800c16b537SWarner Losh #if defined(__GNUC__) 810c16b537SWarner Losh # define UTIL_STATIC static __attribute__((unused)) 820c16b537SWarner Losh #elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) 830c16b537SWarner Losh # define UTIL_STATIC static inline 840c16b537SWarner Losh #elif defined(_MSC_VER) 850c16b537SWarner Losh # define UTIL_STATIC static __inline 860c16b537SWarner Losh #else 870c16b537SWarner Losh # define UTIL_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ 880c16b537SWarner Losh #endif 890c16b537SWarner Losh 900c16b537SWarner Losh 910c16b537SWarner Losh /*-**************************************** 920c16b537SWarner Losh * Console log 930c16b537SWarner Losh ******************************************/ 94a0483764SConrad Meyer extern int g_utilDisplayLevel; 950c16b537SWarner Losh 960c16b537SWarner Losh 970c16b537SWarner Losh /*-**************************************** 980c16b537SWarner Losh * File functions 990c16b537SWarner Losh ******************************************/ 1000c16b537SWarner Losh #if defined(_MSC_VER) 1010c16b537SWarner Losh typedef struct __stat64 stat_t; 102*37f1f268SConrad Meyer typedef int mode_t; 1030c16b537SWarner Losh #else 1040c16b537SWarner Losh typedef struct stat stat_t; 1050c16b537SWarner Losh #endif 1060c16b537SWarner Losh 1070c16b537SWarner Losh 108a0483764SConrad Meyer int UTIL_fileExist(const char* filename); 109a0483764SConrad Meyer int UTIL_isRegularFile(const char* infilename); 110*37f1f268SConrad Meyer int UTIL_isDirectory(const char* infilename); 1112b9c00cbSConrad Meyer int UTIL_isSameFile(const char* file1, const char* file2); 1129cbefe25SConrad Meyer int UTIL_isCompressedFile(const char* infilename, const char *extensionList[]); 113*37f1f268SConrad Meyer int UTIL_isLink(const char* infilename); 114*37f1f268SConrad Meyer int UTIL_isFIFO(const char* infilename); 11519fcbaf1SConrad Meyer 116052d3c12SConrad Meyer #define UTIL_FILESIZE_UNKNOWN ((U64)(-1)) 117a0483764SConrad Meyer U64 UTIL_getFileSize(const char* infilename); 118*37f1f268SConrad Meyer U64 UTIL_getTotalFileSize(const char* const * fileNamesTable, unsigned nbFiles); 119*37f1f268SConrad Meyer int UTIL_getFileStat(const char* infilename, stat_t* statbuf); 120*37f1f268SConrad Meyer int UTIL_setFileStat(const char* filename, stat_t* statbuf); 121*37f1f268SConrad Meyer int UTIL_chmod(char const* filename, mode_t permissions); /*< like chmod, but avoid changing permission of /dev/null */ 122*37f1f268SConrad Meyer int UTIL_compareStr(const void *p1, const void *p2); 123*37f1f268SConrad Meyer const char* UTIL_getFileExtension(const char* infilename); 1240c16b537SWarner Losh 1250c16b537SWarner Losh 126*37f1f268SConrad Meyer /*-**************************************** 127*37f1f268SConrad Meyer * Lists of Filenames 128*37f1f268SConrad Meyer ******************************************/ 129*37f1f268SConrad Meyer 130*37f1f268SConrad Meyer typedef struct 131*37f1f268SConrad Meyer { const char** fileNames; 132*37f1f268SConrad Meyer char* buf; /* fileNames are stored in this buffer (or are read-only) */ 133*37f1f268SConrad Meyer size_t tableSize; /* nb of fileNames */ 134*37f1f268SConrad Meyer size_t tableCapacity; 135*37f1f268SConrad Meyer } FileNamesTable; 136*37f1f268SConrad Meyer 137*37f1f268SConrad Meyer /*! UTIL_createFileNamesTable_fromFileName() : 138*37f1f268SConrad Meyer * read filenames from @inputFileName, and store them into returned object. 139*37f1f268SConrad Meyer * @return : a FileNamesTable*, or NULL in case of error (ex: @inputFileName doesn't exist). 140*37f1f268SConrad Meyer * Note: inputFileSize must be less than 50MB 1410c16b537SWarner Losh */ 142*37f1f268SConrad Meyer FileNamesTable* 143*37f1f268SConrad Meyer UTIL_createFileNamesTable_fromFileName(const char* inputFileName); 1440c16b537SWarner Losh 145*37f1f268SConrad Meyer /*! UTIL_assembleFileNamesTable() : 146*37f1f268SConrad Meyer * This function takes ownership of its arguments, @filenames and @buf, 147*37f1f268SConrad Meyer * and store them inside the created object. 148*37f1f268SConrad Meyer * note : this function never fails, 149*37f1f268SConrad Meyer * it will rather exit() the program if internal allocation fails. 150*37f1f268SConrad Meyer * @return : resulting FileNamesTable* object. 151*37f1f268SConrad Meyer */ 152*37f1f268SConrad Meyer FileNamesTable* 153*37f1f268SConrad Meyer UTIL_assembleFileNamesTable(const char** filenames, size_t tableSize, char* buf); 154*37f1f268SConrad Meyer 155*37f1f268SConrad Meyer /*! UTIL_freeFileNamesTable() : 156*37f1f268SConrad Meyer * This function is compatible with NULL argument and never fails. 157*37f1f268SConrad Meyer */ 158*37f1f268SConrad Meyer void UTIL_freeFileNamesTable(FileNamesTable* table); 159*37f1f268SConrad Meyer 160*37f1f268SConrad Meyer /*! UTIL_mergeFileNamesTable(): 161*37f1f268SConrad Meyer * @return : FileNamesTable*, concatenation of @table1 and @table2 162*37f1f268SConrad Meyer * note: @table1 and @table2 are consumed (freed) by this operation 163*37f1f268SConrad Meyer */ 164*37f1f268SConrad Meyer FileNamesTable* 165*37f1f268SConrad Meyer UTIL_mergeFileNamesTable(FileNamesTable* table1, FileNamesTable* table2); 166*37f1f268SConrad Meyer 167*37f1f268SConrad Meyer 168*37f1f268SConrad Meyer /*! UTIL_expandFNT() : 169*37f1f268SConrad Meyer * read names from @fnt, and expand those corresponding to directories 170*37f1f268SConrad Meyer * update @fnt, now containing only file names, 171*37f1f268SConrad Meyer * @return : 0 in case of success, 1 if error 172*37f1f268SConrad Meyer * note : in case of error, @fnt[0] is NULL 173*37f1f268SConrad Meyer */ 174*37f1f268SConrad Meyer void UTIL_expandFNT(FileNamesTable** fnt, int followLinks); 175*37f1f268SConrad Meyer 176*37f1f268SConrad Meyer /*! UTIL_createFNT_fromROTable() : 177*37f1f268SConrad Meyer * copy the @filenames pointer table inside the returned object. 178*37f1f268SConrad Meyer * The names themselves are still stored in their original buffer, which must outlive the object. 179*37f1f268SConrad Meyer * @return : a FileNamesTable* object, 180*37f1f268SConrad Meyer * or NULL in case of error 181*37f1f268SConrad Meyer */ 182*37f1f268SConrad Meyer FileNamesTable* 183*37f1f268SConrad Meyer UTIL_createFNT_fromROTable(const char** filenames, size_t nbFilenames); 184*37f1f268SConrad Meyer 185*37f1f268SConrad Meyer /*! UTIL_allocateFileNamesTable() : 186*37f1f268SConrad Meyer * Allocates a table of const char*, to insert read-only names later on. 187*37f1f268SConrad Meyer * The created FileNamesTable* doesn't hold a buffer. 188*37f1f268SConrad Meyer * @return : FileNamesTable*, or NULL, if allocation fails. 189*37f1f268SConrad Meyer */ 190*37f1f268SConrad Meyer FileNamesTable* UTIL_allocateFileNamesTable(size_t tableSize); 191*37f1f268SConrad Meyer 192*37f1f268SConrad Meyer 193*37f1f268SConrad Meyer /*! UTIL_refFilename() : 194*37f1f268SConrad Meyer * Add a reference to read-only name into @fnt table. 195*37f1f268SConrad Meyer * As @filename is only referenced, its lifetime must outlive @fnt. 196*37f1f268SConrad Meyer * Internal table must be large enough to reference a new member, 197*37f1f268SConrad Meyer * otherwise its UB (protected by an `assert()`). 198*37f1f268SConrad Meyer */ 199*37f1f268SConrad Meyer void UTIL_refFilename(FileNamesTable* fnt, const char* filename); 200*37f1f268SConrad Meyer 201*37f1f268SConrad Meyer 202*37f1f268SConrad Meyer /* UTIL_createExpandedFNT() is only active if UTIL_HAS_CREATEFILELIST is defined. 203*37f1f268SConrad Meyer * Otherwise, UTIL_createExpandedFNT() is a shell function which does nothing 204*37f1f268SConrad Meyer * apart from displaying a warning message. 205*37f1f268SConrad Meyer */ 2060c16b537SWarner Losh #ifdef _WIN32 2070c16b537SWarner Losh # define UTIL_HAS_CREATEFILELIST 2080c16b537SWarner Losh #elif defined(__linux__) || (PLATFORM_POSIX_VERSION >= 200112L) /* opendir, readdir require POSIX.1-2001 */ 2090c16b537SWarner Losh # define UTIL_HAS_CREATEFILELIST 2100c16b537SWarner Losh #else 211*37f1f268SConrad Meyer /* do not define UTIL_HAS_CREATEFILELIST */ 212*37f1f268SConrad Meyer #endif 2130c16b537SWarner Losh 214*37f1f268SConrad Meyer /*! UTIL_createExpandedFNT() : 215*37f1f268SConrad Meyer * read names from @filenames, and expand those corresponding to directories. 216*37f1f268SConrad Meyer * links are followed or not depending on @followLinks directive. 217*37f1f268SConrad Meyer * @return : an expanded FileNamesTable*, where each name is a file 218*37f1f268SConrad Meyer * or NULL in case of error 2190c16b537SWarner Losh */ 220*37f1f268SConrad Meyer FileNamesTable* 221*37f1f268SConrad Meyer UTIL_createExpandedFNT(const char** filenames, size_t nbFilenames, int followLinks); 2220c16b537SWarner Losh 223*37f1f268SConrad Meyer 224*37f1f268SConrad Meyer /*-**************************************** 225*37f1f268SConrad Meyer * System 226*37f1f268SConrad Meyer ******************************************/ 2270c16b537SWarner Losh 228a0483764SConrad Meyer int UTIL_countPhysicalCores(void); 2290c16b537SWarner Losh 230*37f1f268SConrad Meyer 2310c16b537SWarner Losh #if defined (__cplusplus) 2320c16b537SWarner Losh } 2330c16b537SWarner Losh #endif 2340c16b537SWarner Losh 2350c16b537SWarner Losh #endif /* UTIL_H_MODULE */ 236