xref: /f-stack/freebsd/contrib/zstd/programs/util.h (revision 22ce4aff)
1*22ce4affSfengbojiang /*
2*22ce4affSfengbojiang  * Copyright (c) 2016-2020, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
3*22ce4affSfengbojiang  * All rights reserved.
4*22ce4affSfengbojiang  *
5*22ce4affSfengbojiang  * This source code is licensed under both the BSD-style license (found in the
6*22ce4affSfengbojiang  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7*22ce4affSfengbojiang  * in the COPYING file in the root directory of this source tree).
8*22ce4affSfengbojiang  * You may select, at your option, one of the above-listed licenses.
9*22ce4affSfengbojiang  */
10*22ce4affSfengbojiang 
11*22ce4affSfengbojiang #ifndef UTIL_H_MODULE
12*22ce4affSfengbojiang #define UTIL_H_MODULE
13*22ce4affSfengbojiang 
14*22ce4affSfengbojiang #if defined (__cplusplus)
15*22ce4affSfengbojiang extern "C" {
16*22ce4affSfengbojiang #endif
17*22ce4affSfengbojiang 
18*22ce4affSfengbojiang 
19*22ce4affSfengbojiang /*-****************************************
20*22ce4affSfengbojiang *  Dependencies
21*22ce4affSfengbojiang ******************************************/
22*22ce4affSfengbojiang #include "platform.h"     /* PLATFORM_POSIX_VERSION, ZSTD_NANOSLEEP_SUPPORT, ZSTD_SETPRIORITY_SUPPORT */
23*22ce4affSfengbojiang #include <stddef.h>       /* size_t, ptrdiff_t */
24*22ce4affSfengbojiang #include <sys/types.h>    /* stat, utime */
25*22ce4affSfengbojiang #include <sys/stat.h>     /* stat, chmod */
26*22ce4affSfengbojiang #include "../lib/common/mem.h"          /* U64 */
27*22ce4affSfengbojiang 
28*22ce4affSfengbojiang 
29*22ce4affSfengbojiang /*-************************************************************
30*22ce4affSfengbojiang * Avoid fseek()'s 2GiB barrier with MSVC, macOS, *BSD, MinGW
31*22ce4affSfengbojiang ***************************************************************/
32*22ce4affSfengbojiang #if defined(_MSC_VER) && (_MSC_VER >= 1400)
33*22ce4affSfengbojiang #  define UTIL_fseek _fseeki64
34*22ce4affSfengbojiang #elif !defined(__64BIT__) && (PLATFORM_POSIX_VERSION >= 200112L) /* No point defining Large file for 64 bit */
35*22ce4affSfengbojiang #  define UTIL_fseek fseeko
36*22ce4affSfengbojiang #elif defined(__MINGW32__) && defined(__MSVCRT__) && !defined(__STRICT_ANSI__) && !defined(__NO_MINGW_LFS)
37*22ce4affSfengbojiang #  define UTIL_fseek fseeko64
38*22ce4affSfengbojiang #else
39*22ce4affSfengbojiang #  define UTIL_fseek fseek
40*22ce4affSfengbojiang #endif
41*22ce4affSfengbojiang 
42*22ce4affSfengbojiang 
43*22ce4affSfengbojiang /*-*************************************************
44*22ce4affSfengbojiang *  Sleep & priority functions: Windows - Posix - others
45*22ce4affSfengbojiang ***************************************************/
46*22ce4affSfengbojiang #if defined(_WIN32)
47*22ce4affSfengbojiang #  include <windows.h>
48*22ce4affSfengbojiang #  define SET_REALTIME_PRIORITY SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS)
49*22ce4affSfengbojiang #  define UTIL_sleep(s) Sleep(1000*s)
50*22ce4affSfengbojiang #  define UTIL_sleepMilli(milli) Sleep(milli)
51*22ce4affSfengbojiang 
52*22ce4affSfengbojiang #elif PLATFORM_POSIX_VERSION > 0 /* Unix-like operating system */
53*22ce4affSfengbojiang #  include <unistd.h>   /* sleep */
54*22ce4affSfengbojiang #  define UTIL_sleep(s) sleep(s)
55*22ce4affSfengbojiang #  if ZSTD_NANOSLEEP_SUPPORT   /* necessarily defined in platform.h */
56*22ce4affSfengbojiang #      define UTIL_sleepMilli(milli) { struct timespec t; t.tv_sec=0; t.tv_nsec=milli*1000000ULL; nanosleep(&t, NULL); }
57*22ce4affSfengbojiang #  else
58*22ce4affSfengbojiang #      define UTIL_sleepMilli(milli) /* disabled */
59*22ce4affSfengbojiang #  endif
60*22ce4affSfengbojiang #  if ZSTD_SETPRIORITY_SUPPORT
61*22ce4affSfengbojiang #    include <sys/resource.h> /* setpriority */
62*22ce4affSfengbojiang #    define SET_REALTIME_PRIORITY setpriority(PRIO_PROCESS, 0, -20)
63*22ce4affSfengbojiang #  else
64*22ce4affSfengbojiang #    define SET_REALTIME_PRIORITY /* disabled */
65*22ce4affSfengbojiang #  endif
66*22ce4affSfengbojiang 
67*22ce4affSfengbojiang #else  /* unknown non-unix operating systen */
68*22ce4affSfengbojiang #  define UTIL_sleep(s)          /* disabled */
69*22ce4affSfengbojiang #  define UTIL_sleepMilli(milli) /* disabled */
70*22ce4affSfengbojiang #  define SET_REALTIME_PRIORITY  /* disabled */
71*22ce4affSfengbojiang #endif
72*22ce4affSfengbojiang 
73*22ce4affSfengbojiang 
74*22ce4affSfengbojiang /*-****************************************
75*22ce4affSfengbojiang *  Compiler specifics
76*22ce4affSfengbojiang ******************************************/
77*22ce4affSfengbojiang #if defined(__INTEL_COMPILER)
78*22ce4affSfengbojiang #  pragma warning(disable : 177)    /* disable: message #177: function was declared but never referenced, useful with UTIL_STATIC */
79*22ce4affSfengbojiang #endif
80*22ce4affSfengbojiang #if defined(__GNUC__)
81*22ce4affSfengbojiang #  define UTIL_STATIC static __attribute__((unused))
82*22ce4affSfengbojiang #elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
83*22ce4affSfengbojiang #  define UTIL_STATIC static inline
84*22ce4affSfengbojiang #elif defined(_MSC_VER)
85*22ce4affSfengbojiang #  define UTIL_STATIC static __inline
86*22ce4affSfengbojiang #else
87*22ce4affSfengbojiang #  define UTIL_STATIC static  /* this version may generate warnings for unused static functions; disable the relevant warning */
88*22ce4affSfengbojiang #endif
89*22ce4affSfengbojiang 
90*22ce4affSfengbojiang 
91*22ce4affSfengbojiang /*-****************************************
92*22ce4affSfengbojiang *  Console log
93*22ce4affSfengbojiang ******************************************/
94*22ce4affSfengbojiang extern int g_utilDisplayLevel;
95*22ce4affSfengbojiang 
96*22ce4affSfengbojiang /**
97*22ce4affSfengbojiang  * Displays a message prompt and returns success (0) if first character from stdin
98*22ce4affSfengbojiang  * matches any from acceptableLetters. Otherwise, returns failure (1) and displays abortMsg.
99*22ce4affSfengbojiang  * If any of the inputs are stdin itself, then automatically return failure (1).
100*22ce4affSfengbojiang  */
101*22ce4affSfengbojiang int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, const char* acceptableLetters, int hasStdinInput);
102*22ce4affSfengbojiang 
103*22ce4affSfengbojiang 
104*22ce4affSfengbojiang /*-****************************************
105*22ce4affSfengbojiang *  File functions
106*22ce4affSfengbojiang ******************************************/
107*22ce4affSfengbojiang #if defined(_MSC_VER)
108*22ce4affSfengbojiang     typedef struct __stat64 stat_t;
109*22ce4affSfengbojiang     typedef int mode_t;
110*22ce4affSfengbojiang #elif defined(__MINGW32__) && defined (__MSVCRT__)
111*22ce4affSfengbojiang     typedef struct _stati64 stat_t;
112*22ce4affSfengbojiang #else
113*22ce4affSfengbojiang     typedef struct stat stat_t;
114*22ce4affSfengbojiang #endif
115*22ce4affSfengbojiang 
116*22ce4affSfengbojiang #if defined(_MSC_VER) || defined(__MINGW32__) || defined (__MSVCRT__) /* windows support */
117*22ce4affSfengbojiang #define PATH_SEP '\\'
118*22ce4affSfengbojiang #define STRDUP(s) _strdup(s)
119*22ce4affSfengbojiang #else
120*22ce4affSfengbojiang #define PATH_SEP '/'
121*22ce4affSfengbojiang #include <libgen.h>
122*22ce4affSfengbojiang #define STRDUP(s) strdup(s)
123*22ce4affSfengbojiang #endif
124*22ce4affSfengbojiang 
125*22ce4affSfengbojiang /**
126*22ce4affSfengbojiang  * Calls platform's equivalent of stat() on filename and writes info to statbuf.
127*22ce4affSfengbojiang  * Returns success (1) or failure (0).
128*22ce4affSfengbojiang  */
129*22ce4affSfengbojiang int UTIL_stat(const char* filename, stat_t* statbuf);
130*22ce4affSfengbojiang 
131*22ce4affSfengbojiang /**
132*22ce4affSfengbojiang  * Instead of getting a file's stats, this updates them with the info in the
133*22ce4affSfengbojiang  * provided stat_t. Currently sets owner, group, atime, and mtime. Will only
134*22ce4affSfengbojiang  * update this info for regular files.
135*22ce4affSfengbojiang  */
136*22ce4affSfengbojiang int UTIL_setFileStat(const char* filename, const stat_t* statbuf);
137*22ce4affSfengbojiang 
138*22ce4affSfengbojiang /*
139*22ce4affSfengbojiang  * These helpers operate on a pre-populated stat_t, i.e., the result of
140*22ce4affSfengbojiang  * calling one of the above functions.
141*22ce4affSfengbojiang  */
142*22ce4affSfengbojiang 
143*22ce4affSfengbojiang int UTIL_isRegularFileStat(const stat_t* statbuf);
144*22ce4affSfengbojiang int UTIL_isDirectoryStat(const stat_t* statbuf);
145*22ce4affSfengbojiang int UTIL_isFIFOStat(const stat_t* statbuf);
146*22ce4affSfengbojiang U64 UTIL_getFileSizeStat(const stat_t* statbuf);
147*22ce4affSfengbojiang 
148*22ce4affSfengbojiang /**
149*22ce4affSfengbojiang  * Like chmod(), but only modifies regular files. Provided statbuf may be NULL,
150*22ce4affSfengbojiang  * in which case this function will stat() the file internally, in order to
151*22ce4affSfengbojiang  * check whether it should be modified.
152*22ce4affSfengbojiang  */
153*22ce4affSfengbojiang int UTIL_chmod(char const* filename, const stat_t* statbuf, mode_t permissions);
154*22ce4affSfengbojiang 
155*22ce4affSfengbojiang /*
156*22ce4affSfengbojiang  * In the absence of a pre-existing stat result on the file in question, these
157*22ce4affSfengbojiang  * functions will do a stat() call internally and then use that result to
158*22ce4affSfengbojiang  * compute the needed information.
159*22ce4affSfengbojiang  */
160*22ce4affSfengbojiang 
161*22ce4affSfengbojiang int UTIL_isRegularFile(const char* infilename);
162*22ce4affSfengbojiang int UTIL_isDirectory(const char* infilename);
163*22ce4affSfengbojiang int UTIL_isSameFile(const char* file1, const char* file2);
164*22ce4affSfengbojiang int UTIL_isCompressedFile(const char* infilename, const char *extensionList[]);
165*22ce4affSfengbojiang int UTIL_isLink(const char* infilename);
166*22ce4affSfengbojiang int UTIL_isFIFO(const char* infilename);
167*22ce4affSfengbojiang 
168*22ce4affSfengbojiang #define UTIL_FILESIZE_UNKNOWN  ((U64)(-1))
169*22ce4affSfengbojiang U64 UTIL_getFileSize(const char* infilename);
170*22ce4affSfengbojiang U64 UTIL_getTotalFileSize(const char* const * fileNamesTable, unsigned nbFiles);
171*22ce4affSfengbojiang 
172*22ce4affSfengbojiang int UTIL_compareStr(const void *p1, const void *p2);
173*22ce4affSfengbojiang const char* UTIL_getFileExtension(const char* infilename);
174*22ce4affSfengbojiang void  UTIL_mirrorSourceFilesDirectories(const char** fileNamesTable, unsigned int nbFiles, const char *outDirName);
175*22ce4affSfengbojiang char* UTIL_createMirroredDestDirName(const char* srcFileName, const char* outDirRootName);
176*22ce4affSfengbojiang 
177*22ce4affSfengbojiang 
178*22ce4affSfengbojiang 
179*22ce4affSfengbojiang /*-****************************************
180*22ce4affSfengbojiang  *  Lists of Filenames
181*22ce4affSfengbojiang  ******************************************/
182*22ce4affSfengbojiang 
183*22ce4affSfengbojiang typedef struct
184*22ce4affSfengbojiang {   const char** fileNames;
185*22ce4affSfengbojiang     char* buf;            /* fileNames are stored in this buffer (or are read-only) */
186*22ce4affSfengbojiang     size_t tableSize;     /* nb of fileNames */
187*22ce4affSfengbojiang     size_t tableCapacity;
188*22ce4affSfengbojiang } FileNamesTable;
189*22ce4affSfengbojiang 
190*22ce4affSfengbojiang /*! UTIL_createFileNamesTable_fromFileName() :
191*22ce4affSfengbojiang  *  read filenames from @inputFileName, and store them into returned object.
192*22ce4affSfengbojiang  * @return : a FileNamesTable*, or NULL in case of error (ex: @inputFileName doesn't exist).
193*22ce4affSfengbojiang  *  Note: inputFileSize must be less than 50MB
194*22ce4affSfengbojiang  */
195*22ce4affSfengbojiang FileNamesTable*
196*22ce4affSfengbojiang UTIL_createFileNamesTable_fromFileName(const char* inputFileName);
197*22ce4affSfengbojiang 
198*22ce4affSfengbojiang /*! UTIL_assembleFileNamesTable() :
199*22ce4affSfengbojiang  *  This function takes ownership of its arguments, @filenames and @buf,
200*22ce4affSfengbojiang  *  and store them inside the created object.
201*22ce4affSfengbojiang  *  note : this function never fails,
202*22ce4affSfengbojiang  *         it will rather exit() the program if internal allocation fails.
203*22ce4affSfengbojiang  * @return : resulting FileNamesTable* object.
204*22ce4affSfengbojiang  */
205*22ce4affSfengbojiang FileNamesTable*
206*22ce4affSfengbojiang UTIL_assembleFileNamesTable(const char** filenames, size_t tableSize, char* buf);
207*22ce4affSfengbojiang 
208*22ce4affSfengbojiang /*! UTIL_freeFileNamesTable() :
209*22ce4affSfengbojiang  *  This function is compatible with NULL argument and never fails.
210*22ce4affSfengbojiang  */
211*22ce4affSfengbojiang void UTIL_freeFileNamesTable(FileNamesTable* table);
212*22ce4affSfengbojiang 
213*22ce4affSfengbojiang /*! UTIL_mergeFileNamesTable():
214*22ce4affSfengbojiang  * @return : FileNamesTable*, concatenation of @table1 and @table2
215*22ce4affSfengbojiang  *  note: @table1 and @table2 are consumed (freed) by this operation
216*22ce4affSfengbojiang  */
217*22ce4affSfengbojiang FileNamesTable*
218*22ce4affSfengbojiang UTIL_mergeFileNamesTable(FileNamesTable* table1, FileNamesTable* table2);
219*22ce4affSfengbojiang 
220*22ce4affSfengbojiang 
221*22ce4affSfengbojiang /*! UTIL_expandFNT() :
222*22ce4affSfengbojiang  *  read names from @fnt, and expand those corresponding to directories
223*22ce4affSfengbojiang  *  update @fnt, now containing only file names,
224*22ce4affSfengbojiang  * @return : 0 in case of success, 1 if error
225*22ce4affSfengbojiang  *  note : in case of error, @fnt[0] is NULL
226*22ce4affSfengbojiang  */
227*22ce4affSfengbojiang void UTIL_expandFNT(FileNamesTable** fnt, int followLinks);
228*22ce4affSfengbojiang 
229*22ce4affSfengbojiang /*! UTIL_createFNT_fromROTable() :
230*22ce4affSfengbojiang  *  copy the @filenames pointer table inside the returned object.
231*22ce4affSfengbojiang  *  The names themselves are still stored in their original buffer, which must outlive the object.
232*22ce4affSfengbojiang  * @return : a FileNamesTable* object,
233*22ce4affSfengbojiang  *        or NULL in case of error
234*22ce4affSfengbojiang  */
235*22ce4affSfengbojiang FileNamesTable*
236*22ce4affSfengbojiang UTIL_createFNT_fromROTable(const char** filenames, size_t nbFilenames);
237*22ce4affSfengbojiang 
238*22ce4affSfengbojiang /*! UTIL_allocateFileNamesTable() :
239*22ce4affSfengbojiang  *  Allocates a table of const char*, to insert read-only names later on.
240*22ce4affSfengbojiang  *  The created FileNamesTable* doesn't hold a buffer.
241*22ce4affSfengbojiang  * @return : FileNamesTable*, or NULL, if allocation fails.
242*22ce4affSfengbojiang  */
243*22ce4affSfengbojiang FileNamesTable* UTIL_allocateFileNamesTable(size_t tableSize);
244*22ce4affSfengbojiang 
245*22ce4affSfengbojiang 
246*22ce4affSfengbojiang /*! UTIL_refFilename() :
247*22ce4affSfengbojiang  *  Add a reference to read-only name into @fnt table.
248*22ce4affSfengbojiang  *  As @filename is only referenced, its lifetime must outlive @fnt.
249*22ce4affSfengbojiang  *  Internal table must be large enough to reference a new member,
250*22ce4affSfengbojiang  *  otherwise its UB (protected by an `assert()`).
251*22ce4affSfengbojiang  */
252*22ce4affSfengbojiang void UTIL_refFilename(FileNamesTable* fnt, const char* filename);
253*22ce4affSfengbojiang 
254*22ce4affSfengbojiang 
255*22ce4affSfengbojiang /* UTIL_createExpandedFNT() is only active if UTIL_HAS_CREATEFILELIST is defined.
256*22ce4affSfengbojiang  * Otherwise, UTIL_createExpandedFNT() is a shell function which does nothing
257*22ce4affSfengbojiang  * apart from displaying a warning message.
258*22ce4affSfengbojiang  */
259*22ce4affSfengbojiang #ifdef _WIN32
260*22ce4affSfengbojiang #  define UTIL_HAS_CREATEFILELIST
261*22ce4affSfengbojiang #elif defined(__linux__) || (PLATFORM_POSIX_VERSION >= 200112L)  /* opendir, readdir require POSIX.1-2001 */
262*22ce4affSfengbojiang #  define UTIL_HAS_CREATEFILELIST
263*22ce4affSfengbojiang #  define UTIL_HAS_MIRRORFILELIST
264*22ce4affSfengbojiang #else
265*22ce4affSfengbojiang    /* do not define UTIL_HAS_CREATEFILELIST */
266*22ce4affSfengbojiang #endif
267*22ce4affSfengbojiang 
268*22ce4affSfengbojiang /*! UTIL_createExpandedFNT() :
269*22ce4affSfengbojiang  *  read names from @filenames, and expand those corresponding to directories.
270*22ce4affSfengbojiang  *  links are followed or not depending on @followLinks directive.
271*22ce4affSfengbojiang  * @return : an expanded FileNamesTable*, where each name is a file
272*22ce4affSfengbojiang  *        or NULL in case of error
273*22ce4affSfengbojiang  */
274*22ce4affSfengbojiang FileNamesTable*
275*22ce4affSfengbojiang UTIL_createExpandedFNT(const char** filenames, size_t nbFilenames, int followLinks);
276*22ce4affSfengbojiang 
277*22ce4affSfengbojiang 
278*22ce4affSfengbojiang /*-****************************************
279*22ce4affSfengbojiang  *  System
280*22ce4affSfengbojiang  ******************************************/
281*22ce4affSfengbojiang 
282*22ce4affSfengbojiang int UTIL_countPhysicalCores(void);
283*22ce4affSfengbojiang 
284*22ce4affSfengbojiang 
285*22ce4affSfengbojiang #if defined (__cplusplus)
286*22ce4affSfengbojiang }
287*22ce4affSfengbojiang #endif
288*22ce4affSfengbojiang 
289*22ce4affSfengbojiang #endif /* UTIL_H_MODULE */
290