xref: /netbsd-src/external/bsd/zstd/dist/programs/util.h (revision 3117ece4fc4a4ca4489ba793710b60b0d26bab6c)
1*3117ece4Schristos /*
2*3117ece4Schristos  * Copyright (c) Meta Platforms, Inc. and affiliates.
3*3117ece4Schristos  * All rights reserved.
4*3117ece4Schristos  *
5*3117ece4Schristos  * This source code is licensed under both the BSD-style license (found in the
6*3117ece4Schristos  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7*3117ece4Schristos  * in the COPYING file in the root directory of this source tree).
8*3117ece4Schristos  * You may select, at your option, one of the above-listed licenses.
9*3117ece4Schristos  */
10*3117ece4Schristos 
11*3117ece4Schristos #ifndef UTIL_H_MODULE
12*3117ece4Schristos #define UTIL_H_MODULE
13*3117ece4Schristos 
14*3117ece4Schristos #if defined (__cplusplus)
15*3117ece4Schristos extern "C" {
16*3117ece4Schristos #endif
17*3117ece4Schristos 
18*3117ece4Schristos 
19*3117ece4Schristos /*-****************************************
20*3117ece4Schristos *  Dependencies
21*3117ece4Schristos ******************************************/
22*3117ece4Schristos #include "platform.h"     /* PLATFORM_POSIX_VERSION, ZSTD_NANOSLEEP_SUPPORT, ZSTD_SETPRIORITY_SUPPORT */
23*3117ece4Schristos #include <stddef.h>       /* size_t, ptrdiff_t */
24*3117ece4Schristos #include <sys/types.h>    /* stat, utime */
25*3117ece4Schristos #include <sys/stat.h>     /* stat, chmod */
26*3117ece4Schristos #include "../lib/common/mem.h"          /* U64 */
27*3117ece4Schristos 
28*3117ece4Schristos 
29*3117ece4Schristos /*-************************************************************
30*3117ece4Schristos * Avoid fseek()'s 2GiB barrier with MSVC, macOS, *BSD, MinGW
31*3117ece4Schristos ***************************************************************/
32*3117ece4Schristos #if defined(_MSC_VER) && (_MSC_VER >= 1400)
33*3117ece4Schristos #  define UTIL_fseek _fseeki64
34*3117ece4Schristos #elif !defined(__64BIT__) && (PLATFORM_POSIX_VERSION >= 200112L) /* No point defining Large file for 64 bit */
35*3117ece4Schristos #  define UTIL_fseek fseeko
36*3117ece4Schristos #elif defined(__MINGW32__) && defined(__MSVCRT__) && !defined(__STRICT_ANSI__) && !defined(__NO_MINGW_LFS)
37*3117ece4Schristos #  define UTIL_fseek fseeko64
38*3117ece4Schristos #else
39*3117ece4Schristos #  define UTIL_fseek fseek
40*3117ece4Schristos #endif
41*3117ece4Schristos 
42*3117ece4Schristos 
43*3117ece4Schristos /*-*************************************************
44*3117ece4Schristos *  Sleep & priority functions: Windows - Posix - others
45*3117ece4Schristos ***************************************************/
46*3117ece4Schristos #if defined(_WIN32)
47*3117ece4Schristos #  include <windows.h>
48*3117ece4Schristos #  define SET_REALTIME_PRIORITY SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS)
49*3117ece4Schristos #  define UTIL_sleep(s) Sleep(1000*s)
50*3117ece4Schristos #  define UTIL_sleepMilli(milli) Sleep(milli)
51*3117ece4Schristos 
52*3117ece4Schristos #elif PLATFORM_POSIX_VERSION > 0 /* Unix-like operating system */
53*3117ece4Schristos #  include <unistd.h>   /* sleep */
54*3117ece4Schristos #  define UTIL_sleep(s) sleep(s)
55*3117ece4Schristos #  if ZSTD_NANOSLEEP_SUPPORT   /* necessarily defined in platform.h */
56*3117ece4Schristos #      define UTIL_sleepMilli(milli) { struct timespec t; t.tv_sec=0; t.tv_nsec=milli*1000000ULL; nanosleep(&t, NULL); }
57*3117ece4Schristos #  else
58*3117ece4Schristos #      define UTIL_sleepMilli(milli) /* disabled */
59*3117ece4Schristos #  endif
60*3117ece4Schristos #  if ZSTD_SETPRIORITY_SUPPORT
61*3117ece4Schristos #    include <sys/resource.h> /* setpriority */
62*3117ece4Schristos #    define SET_REALTIME_PRIORITY setpriority(PRIO_PROCESS, 0, -20)
63*3117ece4Schristos #  else
64*3117ece4Schristos #    define SET_REALTIME_PRIORITY /* disabled */
65*3117ece4Schristos #  endif
66*3117ece4Schristos 
67*3117ece4Schristos #else  /* unknown non-unix operating system */
68*3117ece4Schristos #  define UTIL_sleep(s)          /* disabled */
69*3117ece4Schristos #  define UTIL_sleepMilli(milli) /* disabled */
70*3117ece4Schristos #  define SET_REALTIME_PRIORITY  /* disabled */
71*3117ece4Schristos #endif
72*3117ece4Schristos 
73*3117ece4Schristos 
74*3117ece4Schristos /*-****************************************
75*3117ece4Schristos *  Compiler specifics
76*3117ece4Schristos ******************************************/
77*3117ece4Schristos #if defined(__INTEL_COMPILER)
78*3117ece4Schristos #  pragma warning(disable : 177)    /* disable: message #177: function was declared but never referenced, useful with UTIL_STATIC */
79*3117ece4Schristos #endif
80*3117ece4Schristos #if defined(__GNUC__)
81*3117ece4Schristos #  define UTIL_STATIC static __attribute__((unused))
82*3117ece4Schristos #elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
83*3117ece4Schristos #  define UTIL_STATIC static inline
84*3117ece4Schristos #elif defined(_MSC_VER)
85*3117ece4Schristos #  define UTIL_STATIC static __inline
86*3117ece4Schristos #else
87*3117ece4Schristos #  define UTIL_STATIC static  /* this version may generate warnings for unused static functions; disable the relevant warning */
88*3117ece4Schristos #endif
89*3117ece4Schristos 
90*3117ece4Schristos 
91*3117ece4Schristos /*-****************************************
92*3117ece4Schristos *  Console log
93*3117ece4Schristos ******************************************/
94*3117ece4Schristos extern int g_utilDisplayLevel;
95*3117ece4Schristos 
96*3117ece4Schristos /**
97*3117ece4Schristos  * Displays a message prompt and returns success (0) if first character from stdin
98*3117ece4Schristos  * matches any from acceptableLetters. Otherwise, returns failure (1) and displays abortMsg.
99*3117ece4Schristos  * If any of the inputs are stdin itself, then automatically return failure (1).
100*3117ece4Schristos  */
101*3117ece4Schristos int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, const char* acceptableLetters, int hasStdinInput);
102*3117ece4Schristos 
103*3117ece4Schristos 
104*3117ece4Schristos /*-****************************************
105*3117ece4Schristos *  File functions
106*3117ece4Schristos ******************************************/
107*3117ece4Schristos #if defined(_MSC_VER)
108*3117ece4Schristos     typedef struct __stat64 stat_t;
109*3117ece4Schristos     typedef int mode_t;
110*3117ece4Schristos #elif defined(__MINGW32__) && defined (__MSVCRT__)
111*3117ece4Schristos     typedef struct _stati64 stat_t;
112*3117ece4Schristos #else
113*3117ece4Schristos     typedef struct stat stat_t;
114*3117ece4Schristos #endif
115*3117ece4Schristos 
116*3117ece4Schristos #if defined(_MSC_VER) || defined(__MINGW32__) || defined (__MSVCRT__) /* windows support */
117*3117ece4Schristos #define PATH_SEP '\\'
118*3117ece4Schristos #define STRDUP(s) _strdup(s)
119*3117ece4Schristos #else
120*3117ece4Schristos #define PATH_SEP '/'
121*3117ece4Schristos #include <libgen.h>
122*3117ece4Schristos #define STRDUP(s) strdup(s)
123*3117ece4Schristos #endif
124*3117ece4Schristos 
125*3117ece4Schristos 
126*3117ece4Schristos /**
127*3117ece4Schristos  * Calls platform's equivalent of stat() on filename and writes info to statbuf.
128*3117ece4Schristos  * Returns success (1) or failure (0).
129*3117ece4Schristos  *
130*3117ece4Schristos  * UTIL_fstat() is like UTIL_stat() but takes an optional fd that refers to the
131*3117ece4Schristos  * file in question. It turns out that this can be meaningfully faster. If fd is
132*3117ece4Schristos  * -1, behaves just like UTIL_stat() (i.e., falls back to using the filename).
133*3117ece4Schristos  */
134*3117ece4Schristos int UTIL_stat(const char* filename, stat_t* statbuf);
135*3117ece4Schristos int UTIL_fstat(const int fd, const char* filename, stat_t* statbuf);
136*3117ece4Schristos 
137*3117ece4Schristos /**
138*3117ece4Schristos  * Instead of getting a file's stats, this updates them with the info in the
139*3117ece4Schristos  * provided stat_t. Currently sets owner, group, atime, and mtime. Will only
140*3117ece4Schristos  * update this info for regular files.
141*3117ece4Schristos  *
142*3117ece4Schristos  * UTIL_setFDStat() also takes an fd, and will preferentially use that to
143*3117ece4Schristos  * indicate which file to modify, If fd is -1, it will fall back to using the
144*3117ece4Schristos  * filename.
145*3117ece4Schristos  */
146*3117ece4Schristos int UTIL_setFileStat(const char* filename, const stat_t* statbuf);
147*3117ece4Schristos int UTIL_setFDStat(const int fd, const char* filename, const stat_t* statbuf);
148*3117ece4Schristos 
149*3117ece4Schristos /**
150*3117ece4Schristos  * Set atime to now and mtime to the st_mtim in statbuf.
151*3117ece4Schristos  *
152*3117ece4Schristos  * Directly wraps utime() or utimensat(). Returns -1 on error.
153*3117ece4Schristos  * Does not validate filename is valid.
154*3117ece4Schristos  */
155*3117ece4Schristos int UTIL_utime(const char* filename, const stat_t *statbuf);
156*3117ece4Schristos 
157*3117ece4Schristos /*
158*3117ece4Schristos  * These helpers operate on a pre-populated stat_t, i.e., the result of
159*3117ece4Schristos  * calling one of the above functions.
160*3117ece4Schristos  */
161*3117ece4Schristos 
162*3117ece4Schristos int UTIL_isRegularFileStat(const stat_t* statbuf);
163*3117ece4Schristos int UTIL_isDirectoryStat(const stat_t* statbuf);
164*3117ece4Schristos int UTIL_isFIFOStat(const stat_t* statbuf);
165*3117ece4Schristos int UTIL_isBlockDevStat(const stat_t* statbuf);
166*3117ece4Schristos U64 UTIL_getFileSizeStat(const stat_t* statbuf);
167*3117ece4Schristos 
168*3117ece4Schristos /**
169*3117ece4Schristos  * Like chmod(), but only modifies regular files. Provided statbuf may be NULL,
170*3117ece4Schristos  * in which case this function will stat() the file internally, in order to
171*3117ece4Schristos  * check whether it should be modified.
172*3117ece4Schristos  *
173*3117ece4Schristos  * If fd is -1, fd is ignored and the filename is used.
174*3117ece4Schristos  */
175*3117ece4Schristos int UTIL_chmod(char const* filename, const stat_t* statbuf, mode_t permissions);
176*3117ece4Schristos int UTIL_fchmod(const int fd, char const* filename, const stat_t* statbuf, mode_t permissions);
177*3117ece4Schristos 
178*3117ece4Schristos /*
179*3117ece4Schristos  * In the absence of a pre-existing stat result on the file in question, these
180*3117ece4Schristos  * functions will do a stat() call internally and then use that result to
181*3117ece4Schristos  * compute the needed information.
182*3117ece4Schristos  */
183*3117ece4Schristos 
184*3117ece4Schristos int UTIL_isRegularFile(const char* infilename);
185*3117ece4Schristos int UTIL_isDirectory(const char* infilename);
186*3117ece4Schristos int UTIL_isSameFile(const char* file1, const char* file2);
187*3117ece4Schristos int UTIL_isSameFileStat(const char* file1, const char* file2, const stat_t* file1Stat, const stat_t* file2Stat);
188*3117ece4Schristos int UTIL_isCompressedFile(const char* infilename, const char *extensionList[]);
189*3117ece4Schristos int UTIL_isLink(const char* infilename);
190*3117ece4Schristos int UTIL_isFIFO(const char* infilename);
191*3117ece4Schristos 
192*3117ece4Schristos /**
193*3117ece4Schristos  * Returns with the given file descriptor is a console.
194*3117ece4Schristos  * Allows faking whether stdin/stdout/stderr is a console
195*3117ece4Schristos  * using UTIL_fake*IsConsole().
196*3117ece4Schristos  */
197*3117ece4Schristos int UTIL_isConsole(FILE* file);
198*3117ece4Schristos 
199*3117ece4Schristos /**
200*3117ece4Schristos  * Pretends that stdin/stdout/stderr is a console for testing.
201*3117ece4Schristos  */
202*3117ece4Schristos void UTIL_fakeStdinIsConsole(void);
203*3117ece4Schristos void UTIL_fakeStdoutIsConsole(void);
204*3117ece4Schristos void UTIL_fakeStderrIsConsole(void);
205*3117ece4Schristos 
206*3117ece4Schristos /**
207*3117ece4Schristos  * Emit traces for functions that read, or modify file metadata.
208*3117ece4Schristos  */
209*3117ece4Schristos void UTIL_traceFileStat(void);
210*3117ece4Schristos 
211*3117ece4Schristos #define UTIL_FILESIZE_UNKNOWN  ((U64)(-1))
212*3117ece4Schristos U64 UTIL_getFileSize(const char* infilename);
213*3117ece4Schristos U64 UTIL_getTotalFileSize(const char* const * fileNamesTable, unsigned nbFiles);
214*3117ece4Schristos 
215*3117ece4Schristos /**
216*3117ece4Schristos  * Take @size in bytes,
217*3117ece4Schristos  * prepare the components to pretty-print it in a scaled way.
218*3117ece4Schristos  * The components in the returned struct should be passed in
219*3117ece4Schristos  * precision, value, suffix order to a "%.*f%s" format string.
220*3117ece4Schristos  * Output policy is sensible to @g_utilDisplayLevel,
221*3117ece4Schristos  * for verbose mode (@g_utilDisplayLevel >= 4),
222*3117ece4Schristos  * does not scale down.
223*3117ece4Schristos  */
224*3117ece4Schristos typedef struct {
225*3117ece4Schristos   double value;
226*3117ece4Schristos   int precision;
227*3117ece4Schristos   const char* suffix;
228*3117ece4Schristos } UTIL_HumanReadableSize_t;
229*3117ece4Schristos 
230*3117ece4Schristos UTIL_HumanReadableSize_t UTIL_makeHumanReadableSize(U64 size);
231*3117ece4Schristos 
232*3117ece4Schristos int UTIL_compareStr(const void *p1, const void *p2);
233*3117ece4Schristos const char* UTIL_getFileExtension(const char* infilename);
234*3117ece4Schristos void  UTIL_mirrorSourceFilesDirectories(const char** fileNamesTable, unsigned int nbFiles, const char *outDirName);
235*3117ece4Schristos char* UTIL_createMirroredDestDirName(const char* srcFileName, const char* outDirRootName);
236*3117ece4Schristos 
237*3117ece4Schristos 
238*3117ece4Schristos 
239*3117ece4Schristos /*-****************************************
240*3117ece4Schristos  *  Lists of Filenames
241*3117ece4Schristos  ******************************************/
242*3117ece4Schristos 
243*3117ece4Schristos typedef struct
244*3117ece4Schristos {   const char** fileNames;
245*3117ece4Schristos     char* buf;            /* fileNames are stored in this buffer (or are read-only) */
246*3117ece4Schristos     size_t tableSize;     /* nb of fileNames */
247*3117ece4Schristos     size_t tableCapacity;
248*3117ece4Schristos } FileNamesTable;
249*3117ece4Schristos 
250*3117ece4Schristos /*! UTIL_createFileNamesTable_fromFileName() :
251*3117ece4Schristos  *  read filenames from @inputFileName, and store them into returned object.
252*3117ece4Schristos  * @return : a FileNamesTable*, or NULL in case of error (ex: @inputFileName doesn't exist).
253*3117ece4Schristos  *  Note: inputFileSize must be less than 50MB
254*3117ece4Schristos  */
255*3117ece4Schristos FileNamesTable*
256*3117ece4Schristos UTIL_createFileNamesTable_fromFileName(const char* inputFileName);
257*3117ece4Schristos 
258*3117ece4Schristos /*! UTIL_assembleFileNamesTable() :
259*3117ece4Schristos  *  This function takes ownership of its arguments, @filenames and @buf,
260*3117ece4Schristos  *  and store them inside the created object.
261*3117ece4Schristos  *  note : this function never fails,
262*3117ece4Schristos  *         it will rather exit() the program if internal allocation fails.
263*3117ece4Schristos  * @return : resulting FileNamesTable* object.
264*3117ece4Schristos  */
265*3117ece4Schristos FileNamesTable*
266*3117ece4Schristos UTIL_assembleFileNamesTable(const char** filenames, size_t tableSize, char* buf);
267*3117ece4Schristos 
268*3117ece4Schristos /*! UTIL_freeFileNamesTable() :
269*3117ece4Schristos  *  This function is compatible with NULL argument and never fails.
270*3117ece4Schristos  */
271*3117ece4Schristos void UTIL_freeFileNamesTable(FileNamesTable* table);
272*3117ece4Schristos 
273*3117ece4Schristos /*! UTIL_mergeFileNamesTable():
274*3117ece4Schristos  * @return : FileNamesTable*, concatenation of @table1 and @table2
275*3117ece4Schristos  *  note: @table1 and @table2 are consumed (freed) by this operation
276*3117ece4Schristos  */
277*3117ece4Schristos FileNamesTable*
278*3117ece4Schristos UTIL_mergeFileNamesTable(FileNamesTable* table1, FileNamesTable* table2);
279*3117ece4Schristos 
280*3117ece4Schristos 
281*3117ece4Schristos /*! UTIL_expandFNT() :
282*3117ece4Schristos  *  read names from @fnt, and expand those corresponding to directories
283*3117ece4Schristos  *  update @fnt, now containing only file names,
284*3117ece4Schristos  *  note : in case of error, @fnt[0] is NULL
285*3117ece4Schristos  */
286*3117ece4Schristos void UTIL_expandFNT(FileNamesTable** fnt, int followLinks);
287*3117ece4Schristos 
288*3117ece4Schristos /*! UTIL_createFNT_fromROTable() :
289*3117ece4Schristos  *  copy the @filenames pointer table inside the returned object.
290*3117ece4Schristos  *  The names themselves are still stored in their original buffer, which must outlive the object.
291*3117ece4Schristos  * @return : a FileNamesTable* object,
292*3117ece4Schristos  *        or NULL in case of error
293*3117ece4Schristos  */
294*3117ece4Schristos FileNamesTable*
295*3117ece4Schristos UTIL_createFNT_fromROTable(const char** filenames, size_t nbFilenames);
296*3117ece4Schristos 
297*3117ece4Schristos /*! UTIL_allocateFileNamesTable() :
298*3117ece4Schristos  *  Allocates a table of const char*, to insert read-only names later on.
299*3117ece4Schristos  *  The created FileNamesTable* doesn't hold a buffer.
300*3117ece4Schristos  * @return : FileNamesTable*, or NULL, if allocation fails.
301*3117ece4Schristos  */
302*3117ece4Schristos FileNamesTable* UTIL_allocateFileNamesTable(size_t tableSize);
303*3117ece4Schristos 
304*3117ece4Schristos /*! UTIL_searchFileNamesTable() :
305*3117ece4Schristos  *  Searched through entries in FileNamesTable for a specific name.
306*3117ece4Schristos  * @return : index of entry if found or -1 if not found
307*3117ece4Schristos  */
308*3117ece4Schristos int UTIL_searchFileNamesTable(FileNamesTable* table, char const* name);
309*3117ece4Schristos 
310*3117ece4Schristos /*! UTIL_refFilename() :
311*3117ece4Schristos  *  Add a reference to read-only name into @fnt table.
312*3117ece4Schristos  *  As @filename is only referenced, its lifetime must outlive @fnt.
313*3117ece4Schristos  *  Internal table must be large enough to reference a new member,
314*3117ece4Schristos  *  otherwise its UB (protected by an `assert()`).
315*3117ece4Schristos  */
316*3117ece4Schristos void UTIL_refFilename(FileNamesTable* fnt, const char* filename);
317*3117ece4Schristos 
318*3117ece4Schristos 
319*3117ece4Schristos /* UTIL_createExpandedFNT() is only active if UTIL_HAS_CREATEFILELIST is defined.
320*3117ece4Schristos  * Otherwise, UTIL_createExpandedFNT() is a shell function which does nothing
321*3117ece4Schristos  * apart from displaying a warning message.
322*3117ece4Schristos  */
323*3117ece4Schristos #ifdef _WIN32
324*3117ece4Schristos #  define UTIL_HAS_CREATEFILELIST
325*3117ece4Schristos #elif defined(__linux__) || (PLATFORM_POSIX_VERSION >= 200112L)  /* opendir, readdir require POSIX.1-2001 */
326*3117ece4Schristos #  define UTIL_HAS_CREATEFILELIST
327*3117ece4Schristos #  define UTIL_HAS_MIRRORFILELIST
328*3117ece4Schristos #else
329*3117ece4Schristos    /* do not define UTIL_HAS_CREATEFILELIST */
330*3117ece4Schristos #endif
331*3117ece4Schristos 
332*3117ece4Schristos /*! UTIL_createExpandedFNT() :
333*3117ece4Schristos  *  read names from @filenames, and expand those corresponding to directories.
334*3117ece4Schristos  *  links are followed or not depending on @followLinks directive.
335*3117ece4Schristos  * @return : an expanded FileNamesTable*, where each name is a file
336*3117ece4Schristos  *        or NULL in case of error
337*3117ece4Schristos  */
338*3117ece4Schristos FileNamesTable*
339*3117ece4Schristos UTIL_createExpandedFNT(const char* const* filenames, size_t nbFilenames, int followLinks);
340*3117ece4Schristos 
341*3117ece4Schristos #if defined(_WIN32)
342*3117ece4Schristos DWORD CountSetBits(ULONG_PTR bitMask);
343*3117ece4Schristos #endif
344*3117ece4Schristos 
345*3117ece4Schristos /*-****************************************
346*3117ece4Schristos  *  System
347*3117ece4Schristos  ******************************************/
348*3117ece4Schristos 
349*3117ece4Schristos int UTIL_countCores(int logical);
350*3117ece4Schristos 
351*3117ece4Schristos int UTIL_countPhysicalCores(void);
352*3117ece4Schristos 
353*3117ece4Schristos int UTIL_countLogicalCores(void);
354*3117ece4Schristos 
355*3117ece4Schristos #if defined (__cplusplus)
356*3117ece4Schristos }
357*3117ece4Schristos #endif
358*3117ece4Schristos 
359*3117ece4Schristos #endif /* UTIL_H_MODULE */
360