Rizin
unix-like reverse engineering framework and cli tools
util.h
Go to the documentation of this file.
1 /*
2  util.h - utility functions
3  Copyright (C) 2016-present, Przemyslaw Skibinski, Yann Collet
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License along
16  with this program; if not, write to the Free Software Foundation, Inc.,
17  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 
20 #ifndef UTIL_H_MODULE
21 #define UTIL_H_MODULE
22 
23 #if defined (__cplusplus)
24 extern "C" {
25 #endif
26 
27 
28 
29 /*-****************************************
30 * Dependencies
31 ******************************************/
32 #include "platform.h" /* PLATFORM_POSIX_VERSION */
33 #include <stddef.h> /* size_t, ptrdiff_t */
34 #include <stdlib.h> /* malloc */
35 #include <string.h> /* strlen, strncpy */
36 #include <stdio.h> /* fprintf, fileno */
37 #include <assert.h>
38 #include <sys/types.h> /* stat, utime */
39 #include <sys/stat.h> /* stat */
40 #if defined(_WIN32)
41 # include <sys/utime.h> /* utime */
42 # include <io.h> /* _chmod */
43 #else
44 # include <unistd.h> /* chown, stat */
45 # if PLATFORM_POSIX_VERSION < 200809L
46 # include <utime.h> /* utime */
47 # else
48 # include <fcntl.h> /* AT_FDCWD */
49 # include <sys/stat.h> /* for utimensat */
50 # endif
51 #endif
52 #include <time.h> /* time */
53 #include <limits.h> /* INT_MAX */
54 #include <errno.h>
55 
56 
57 
58 /*-**************************************************************
59 * Basic Types
60 *****************************************************************/
61 #if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
62 # include <stdint.h>
63  typedef uint8_t BYTE;
64  typedef uint16_t U16;
65  typedef int16_t S16;
66  typedef uint32_t U32;
67  typedef int32_t S32;
68  typedef uint64_t U64;
69  typedef int64_t S64;
70 #else
71  typedef unsigned char BYTE;
72  typedef unsigned short U16;
73  typedef signed short S16;
74  typedef unsigned int U32;
75  typedef signed int S32;
76  typedef unsigned long long U64;
77  typedef signed long long S64;
78 #endif
79 
80 
81 /* ************************************************************
82 * Avoid fseek()'s 2GiB barrier with MSVC, MacOS, *BSD, MinGW
83 ***************************************************************/
84 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
85 # define UTIL_fseek _fseeki64
86 #elif !defined(__64BIT__) && (PLATFORM_POSIX_VERSION >= 200112L) /* No point defining Large file for 64 bit */
87 # define UTIL_fseek fseeko
88 #elif defined(__MINGW32__) && defined(__MSVCRT__) && !defined(__STRICT_ANSI__) && !defined(__NO_MINGW_LFS)
89 # define UTIL_fseek fseeko64
90 #else
91 # define UTIL_fseek fseek
92 #endif
93 
94 
95 /*-****************************************
96 * Sleep functions: Windows - Posix - others
97 ******************************************/
98 #if defined(_WIN32)
99 # include <windows.h>
100 # define SET_REALTIME_PRIORITY SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS)
101 # define UTIL_sleep(s) Sleep(1000*s)
102 # define UTIL_sleepMilli(milli) Sleep(milli)
103 #elif PLATFORM_POSIX_VERSION >= 0 /* Unix-like operating system */
104 # include <unistd.h>
105 # include <sys/resource.h> /* setpriority */
106 # include <time.h> /* clock_t, nanosleep, clock, CLOCKS_PER_SEC */
107 # if defined(PRIO_PROCESS)
108 # define SET_REALTIME_PRIORITY setpriority(PRIO_PROCESS, 0, -20)
109 # else
110 # define SET_REALTIME_PRIORITY /* disabled */
111 # endif
112 # define UTIL_sleep(s) sleep(s)
113 # if (defined(__linux__) && (PLATFORM_POSIX_VERSION >= 199309L)) || (PLATFORM_POSIX_VERSION >= 200112L) /* nanosleep requires POSIX.1-2001 */
114 # define UTIL_sleepMilli(milli) { struct timespec t; t.tv_sec=0; t.tv_nsec=milli*1000000ULL; nanosleep(&t, NULL); }
115 # else
116 # define UTIL_sleepMilli(milli) /* disabled */
117 # endif
118 #else
119 # define SET_REALTIME_PRIORITY /* disabled */
120 # define UTIL_sleep(s) /* disabled */
121 # define UTIL_sleepMilli(milli) /* disabled */
122 #endif
123 
124 
125 /*-****************************************
126 * stat() functions
127 ******************************************/
128 #if defined(_MSC_VER)
129 # define UTIL_TYPE_stat __stat64
130 # define UTIL_stat _stat64
131 # define UTIL_fstat _fstat64
132 # define UTIL_STAT_MODE_ISREG(st_mode) ((st_mode) & S_IFREG)
133 #elif defined(__MINGW32__) && defined (__MSVCRT__)
134 # define UTIL_TYPE_stat _stati64
135 # define UTIL_stat _stati64
136 # define UTIL_fstat _fstati64
137 # define UTIL_STAT_MODE_ISREG(st_mode) ((st_mode) & S_IFREG)
138 #else
139 # define UTIL_TYPE_stat stat
140 # define UTIL_stat stat
141 # define UTIL_fstat fstat
142 # define UTIL_STAT_MODE_ISREG(st_mode) (S_ISREG(st_mode))
143 #endif
144 
145 
146 /*-****************************************
147 * fileno() function
148 ******************************************/
149 #if defined(_MSC_VER)
150 # define UTIL_fileno _fileno
151 #else
152 # define UTIL_fileno fileno
153 #endif
154 
155 /* *************************************
156 * Constants
157 ***************************************/
158 #define LIST_SIZE_INCREASE (8*1024)
159 
160 
161 /*-****************************************
162 * Compiler specifics
163 ******************************************/
164 #if defined(__INTEL_COMPILER)
165 # pragma warning(disable : 177) /* disable: message #177: function was declared but never referenced, useful with UTIL_STATIC */
166 #endif
167 #if defined(__GNUC__)
168 # define UTIL_STATIC static __attribute__((unused))
169 #elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
170 # define UTIL_STATIC static inline
171 #elif defined(_MSC_VER)
172 # define UTIL_STATIC static __inline
173 #else
174 # define UTIL_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
175 #endif
176 
177 
178 /*-****************************************
179 * Time functions
180 ******************************************/
181 #if defined(_WIN32) /* Windows */
182 
183  typedef LARGE_INTEGER UTIL_time_t;
184  UTIL_STATIC UTIL_time_t UTIL_getTime(void) { UTIL_time_t x; QueryPerformanceCounter(&x); return x; }
186  {
187  static LARGE_INTEGER ticksPerSecond;
188  static int init = 0;
189  if (!init) {
190  if (!QueryPerformanceFrequency(&ticksPerSecond))
191  fprintf(stderr, "ERROR: QueryPerformanceFrequency() failure\n");
192  init = 1;
193  }
194  return 1000000ULL*(clockEnd.QuadPart - clockStart.QuadPart)/ticksPerSecond.QuadPart;
195  }
197  {
198  static LARGE_INTEGER ticksPerSecond;
199  static int init = 0;
200  if (!init) {
201  if (!QueryPerformanceFrequency(&ticksPerSecond))
202  fprintf(stderr, "ERROR: QueryPerformanceFrequency() failure\n");
203  init = 1;
204  }
205  return 1000000000ULL*(clockEnd.QuadPart - clockStart.QuadPart)/ticksPerSecond.QuadPart;
206  }
207 
208 #elif defined(__APPLE__) && defined(__MACH__)
209 
210  #include <mach/mach_time.h>
211  typedef U64 UTIL_time_t;
212  UTIL_STATIC UTIL_time_t UTIL_getTime(void) { return mach_absolute_time(); }
214  {
215  static mach_timebase_info_data_t rate;
216  static int init = 0;
217  if (!init) {
218  mach_timebase_info(&rate);
219  init = 1;
220  }
221  return (((clockEnd - clockStart) * (U64)rate.numer) / ((U64)rate.denom)) / 1000ULL;
222  }
224  {
225  static mach_timebase_info_data_t rate;
226  static int init = 0;
227  if (!init) {
228  mach_timebase_info(&rate);
229  init = 1;
230  }
231  return ((clockEnd - clockStart) * (U64)rate.numer) / ((U64)rate.denom);
232  }
233 
234 #elif (PLATFORM_POSIX_VERSION >= 200112L) && (defined __UCLIBC__ || (defined(__GLIBC__) && ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 17) || __GLIBC__ > 2) ) )
235 
236  #include <time.h>
237  typedef struct timespec UTIL_time_t;
239  {
240  UTIL_time_t now;
241  if (clock_gettime(CLOCK_MONOTONIC, &now))
242  fprintf(stderr, "ERROR: Failed to get time\n"); /* we could also exit() */
243  return now;
244  }
245  UTIL_STATIC UTIL_time_t UTIL_getSpanTime(UTIL_time_t begin, UTIL_time_t end)
246  {
247  UTIL_time_t diff;
248  if (end.tv_nsec < begin.tv_nsec) {
249  diff.tv_sec = (end.tv_sec - 1) - begin.tv_sec;
250  diff.tv_nsec = (end.tv_nsec + 1000000000ULL) - begin.tv_nsec;
251  } else {
252  diff.tv_sec = end.tv_sec - begin.tv_sec;
253  diff.tv_nsec = end.tv_nsec - begin.tv_nsec;
254  }
255  return diff;
256  }
258  {
259  UTIL_time_t const diff = UTIL_getSpanTime(begin, end);
260  U64 micro = 0;
261  micro += 1000000ULL * diff.tv_sec;
262  micro += diff.tv_nsec / 1000ULL;
263  return micro;
264  }
266  {
267  UTIL_time_t const diff = UTIL_getSpanTime(begin, end);
268  U64 nano = 0;
269  nano += 1000000000ULL * diff.tv_sec;
270  nano += diff.tv_nsec;
271  return nano;
272  }
273 
274 #else /* relies on standard C (note : clock_t measurements can be wrong when using multi-threading) */
275 
277  UTIL_STATIC UTIL_time_t UTIL_getTime(void) { return clock(); }
278  UTIL_STATIC U64 UTIL_getSpanTimeMicro(UTIL_time_t clockStart, UTIL_time_t clockEnd) { return 1000000ULL * (clockEnd - clockStart) / CLOCKS_PER_SEC; }
279  UTIL_STATIC U64 UTIL_getSpanTimeNano(UTIL_time_t clockStart, UTIL_time_t clockEnd) { return 1000000000ULL * (clockEnd - clockStart) / CLOCKS_PER_SEC; }
280 #endif
281 
282 
283 /* returns time span in microseconds */
285 {
286  UTIL_time_t const clockEnd = UTIL_getTime();
287  return UTIL_getSpanTimeMicro(clockStart, clockEnd);
288 }
289 
290 /* returns time span in nanoseconds */
292 {
293  UTIL_time_t const clockEnd = UTIL_getTime();
294  return UTIL_getSpanTimeNano(clockStart, clockEnd);
295 }
296 
298 {
299  UTIL_time_t const clockStart = UTIL_getTime();
300  UTIL_time_t clockEnd;
301  do {
302  clockEnd = UTIL_getTime();
303  } while (UTIL_getSpanTimeNano(clockStart, clockEnd) == 0);
304 }
305 
306 
307 
308 /*-****************************************
309 * File functions
310 ******************************************/
311 #if defined(_MSC_VER)
312  #define chmod _chmod
313  typedef struct __stat64 stat_t;
314 #else
315  typedef struct stat stat_t;
316 #endif
317 
318 
319 UTIL_STATIC int UTIL_isRegFile(const char* infilename);
320 
321 
322 UTIL_STATIC int UTIL_setFileStat(const char *filename, stat_t *statbuf)
323 {
324  int res = 0;
325 
326  if (!UTIL_isRegFile(filename))
327  return -1;
328 
329  {
330 #if defined(_WIN32) || (PLATFORM_POSIX_VERSION < 200809L)
331  struct utimbuf timebuf;
332  timebuf.actime = time(NULL);
333  timebuf.modtime = statbuf->st_mtime;
334  res += utime(filename, &timebuf); /* set access and modification times */
335 #else
336  struct timespec timebuf[2] = {};
337  timebuf[0].tv_nsec = UTIME_NOW;
338  timebuf[1].tv_sec = statbuf->st_mtime;
339  res += utimensat(AT_FDCWD, filename, timebuf, 0); /* set access and modification times */
340 #endif
341  }
342 
343 #if !defined(_WIN32)
344  res += chown(filename, statbuf->st_uid, statbuf->st_gid); /* Copy ownership */
345 #endif
346 
347  res += chmod(filename, statbuf->st_mode & 07777); /* Copy file permissions */
348 
349  errno = 0;
350  return -res; /* number of errors is returned */
351 }
352 
353 
354 UTIL_STATIC int UTIL_getFileStat(const char* infilename, stat_t *statbuf)
355 {
356  int r;
357 #if defined(_MSC_VER)
358  r = _stat64(infilename, statbuf);
359  if (r || !(statbuf->st_mode & S_IFREG)) return 0; /* No good... */
360 #else
361  r = stat(infilename, statbuf);
362  if (r || !S_ISREG(statbuf->st_mode)) return 0; /* No good... */
363 #endif
364  return 1;
365 }
366 
367 
368 UTIL_STATIC int UTIL_isRegFile(const char* infilename)
369 {
370  stat_t statbuf;
371  return UTIL_getFileStat(infilename, &statbuf); /* Only need to know whether it is a regular file */
372 }
373 
374 
375 UTIL_STATIC U32 UTIL_isDirectory(const char* infilename)
376 {
377  int r;
378  stat_t statbuf;
379 #if defined(_MSC_VER)
380  r = _stat64(infilename, &statbuf);
381  if (!r && (statbuf.st_mode & _S_IFDIR)) return 1;
382 #else
383  r = stat(infilename, &statbuf);
384  if (!r && S_ISDIR(statbuf.st_mode)) return 1;
385 #endif
386  return 0;
387 }
388 
389 
391 {
392  int r;
393  int fd;
394  struct UTIL_TYPE_stat statbuf;
395 
396  fd = UTIL_fileno(file);
397  if (fd < 0) {
398  perror("fileno");
399  exit(1);
400  }
401  r = UTIL_fstat(fd, &statbuf);
402  if (r || !UTIL_STAT_MODE_ISREG(statbuf.st_mode)) return 0; /* No good... */
403  return (U64)statbuf.st_size;
404 }
405 
406 
407 UTIL_STATIC U64 UTIL_getFileSize(const char* infilename)
408 {
409  int r;
410  struct UTIL_TYPE_stat statbuf;
411 
412  r = UTIL_stat(infilename, &statbuf);
413  if (r || !UTIL_STAT_MODE_ISREG(statbuf.st_mode)) return 0; /* No good... */
414  return (U64)statbuf.st_size;
415 }
416 
417 
418 UTIL_STATIC U64 UTIL_getTotalFileSize(const char** fileNamesTable, unsigned nbFiles)
419 {
420  U64 total = 0;
421  unsigned n;
422  for (n=0; n<nbFiles; n++)
423  total += UTIL_getFileSize(fileNamesTable[n]);
424  return total;
425 }
426 
427 
428 /*
429  * A modified version of realloc().
430  * If UTIL_realloc() fails the original block is freed.
431 */
432 UTIL_STATIC void* UTIL_realloc(void* ptr, size_t size)
433 {
434  void* const newptr = realloc(ptr, size);
435  if (newptr) return newptr;
436  free(ptr);
437  return NULL;
438 }
439 
440 
441 #ifdef _WIN32
442 # define UTIL_HAS_CREATEFILELIST
443 
444 UTIL_STATIC int UTIL_prepareFileList(const char* dirName, char** bufStart, size_t* pos, char** bufEnd)
445 {
446  char* path;
447  size_t dirLength, nbFiles = 0;
448  WIN32_FIND_DATAA cFile;
449  HANDLE hFile;
450 
451  dirLength = strlen(dirName);
452  path = (char*) malloc(dirLength + 3);
453  if (!path) return 0;
454 
455  memcpy(path, dirName, dirLength);
456  path[dirLength] = '\\';
457  path[dirLength+1] = '*';
458  path[dirLength+2] = 0;
459 
460  hFile=FindFirstFileA(path, &cFile);
461  if (hFile == INVALID_HANDLE_VALUE) {
462  fprintf(stderr, "Cannot open directory '%s'\n", dirName);
463  return 0;
464  }
465  free(path);
466 
467  do {
468  size_t pathLength;
469  int const fnameLength = (int)strlen(cFile.cFileName);
470  path = (char*) malloc(dirLength + fnameLength + 2);
471  if (!path) { FindClose(hFile); return 0; }
472  memcpy(path, dirName, dirLength);
473  path[dirLength] = '\\';
474  memcpy(path+dirLength+1, cFile.cFileName, fnameLength);
475  pathLength = dirLength+1+fnameLength;
476  path[pathLength] = 0;
477  if (cFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
478  if (strcmp (cFile.cFileName, "..") == 0 ||
479  strcmp (cFile.cFileName, ".") == 0) continue;
480 
481  nbFiles += UTIL_prepareFileList(path, bufStart, pos, bufEnd); /* Recursively call "UTIL_prepareFileList" with the new path. */
482  if (*bufStart == NULL) { free(path); FindClose(hFile); return 0; }
483  }
484  else if ((cFile.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) || (cFile.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) || (cFile.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED)) {
485  if (*bufStart + *pos + pathLength >= *bufEnd) {
486  ptrdiff_t newListSize = (*bufEnd - *bufStart) + LIST_SIZE_INCREASE;
487  *bufStart = (char*)UTIL_realloc(*bufStart, newListSize);
488  *bufEnd = *bufStart + newListSize;
489  if (*bufStart == NULL) { free(path); FindClose(hFile); return 0; }
490  }
491  if (*bufStart + *pos + pathLength < *bufEnd) {
492  strncpy(*bufStart + *pos, path, *bufEnd - (*bufStart + *pos));
493  *pos += pathLength + 1;
494  nbFiles++;
495  }
496  }
497  free(path);
498  } while (FindNextFileA(hFile, &cFile));
499 
500  FindClose(hFile);
501  assert(nbFiles < INT_MAX);
502  return (int)nbFiles;
503 }
504 
505 #elif defined(__linux__) || (PLATFORM_POSIX_VERSION >= 200112L) /* opendir, readdir require POSIX.1-2001 */
506 # define UTIL_HAS_CREATEFILELIST
507 # include <dirent.h> /* opendir, readdir */
508 # include <string.h> /* strerror, memcpy */
509 
510 UTIL_STATIC int UTIL_prepareFileList(const char* dirName, char** bufStart, size_t* pos, char** bufEnd)
511 {
512  DIR* dir;
513  struct dirent * entry;
514  int dirLength, nbFiles = 0;
515 
516  if (!(dir = opendir(dirName))) {
517  fprintf(stderr, "Cannot open directory '%s': %s\n", dirName, strerror(errno));
518  return 0;
519  }
520 
521  dirLength = (int)strlen(dirName);
522  errno = 0;
523  while ((entry = readdir(dir)) != NULL) {
524  char* path;
525  int fnameLength, pathLength;
526  if (strcmp (entry->d_name, "..") == 0 ||
527  strcmp (entry->d_name, ".") == 0) continue;
528  fnameLength = (int)strlen(entry->d_name);
529  path = (char*) malloc(dirLength + fnameLength + 2);
530  if (!path) { closedir(dir); return 0; }
531  memcpy(path, dirName, dirLength);
532  path[dirLength] = '/';
533  memcpy(path+dirLength+1, entry->d_name, fnameLength);
534  pathLength = dirLength+1+fnameLength;
535  path[pathLength] = 0;
536 
537  if (UTIL_isDirectory(path)) {
538  nbFiles += UTIL_prepareFileList(path, bufStart, pos, bufEnd); /* Recursively call "UTIL_prepareFileList" with the new path. */
539  if (*bufStart == NULL) { free(path); closedir(dir); return 0; }
540  } else {
541  if (*bufStart + *pos + pathLength >= *bufEnd) {
542  ptrdiff_t newListSize = (*bufEnd - *bufStart) + LIST_SIZE_INCREASE;
543  *bufStart = (char*)UTIL_realloc(*bufStart, newListSize);
544  *bufEnd = *bufStart + newListSize;
545  if (*bufStart == NULL) { free(path); closedir(dir); return 0; }
546  }
547  if (*bufStart + *pos + pathLength < *bufEnd) {
548  strncpy(*bufStart + *pos, path, *bufEnd - (*bufStart + *pos));
549  *pos += pathLength + 1;
550  nbFiles++;
551  }
552  }
553  free(path);
554  errno = 0; /* clear errno after UTIL_isDirectory, UTIL_prepareFileList */
555  }
556 
557  if (errno != 0) {
558  fprintf(stderr, "readdir(%s) error: %s\n", dirName, strerror(errno));
559  free(*bufStart);
560  *bufStart = NULL;
561  }
562  closedir(dir);
563  return nbFiles;
564 }
565 
566 #else
567 
568 UTIL_STATIC int UTIL_prepareFileList(const char* dirName, char** bufStart, size_t* pos, char** bufEnd)
569 {
570  (void)bufStart; (void)bufEnd; (void)pos;
571  fprintf(stderr, "Directory %s ignored (compiled without _WIN32 or _POSIX_C_SOURCE)\n", dirName);
572  return 0;
573 }
574 
575 #endif /* #ifdef _WIN32 */
576 
577 /*
578  * UTIL_createFileList - takes a list of files and directories (params: inputNames, inputNamesNb), scans directories,
579  * and returns a new list of files (params: return value, allocatedBuffer, allocatedNamesNb).
580  * After finishing usage of the list the structures should be freed with UTIL_freeFileList(params: return value, allocatedBuffer)
581  * In case of error UTIL_createFileList returns NULL and UTIL_freeFileList should not be called.
582  */
583 UTIL_STATIC const char**
584 UTIL_createFileList(const char** inputNames, unsigned inputNamesNb,
585  char** allocatedBuffer, unsigned* allocatedNamesNb)
586 {
587  size_t pos;
588  unsigned i, nbFiles;
589  char* buf = (char*)malloc(LIST_SIZE_INCREASE);
590  size_t bufSize = LIST_SIZE_INCREASE;
591  const char** fileTable;
592 
593  if (!buf) return NULL;
594 
595  for (i=0, pos=0, nbFiles=0; i<inputNamesNb; i++) {
596  if (!UTIL_isDirectory(inputNames[i])) {
597  size_t const len = strlen(inputNames[i]) + 1; /* include nul char */
598  if (pos + len >= bufSize) {
599  while (pos + len >= bufSize) bufSize += LIST_SIZE_INCREASE;
600  buf = (char*)UTIL_realloc(buf, bufSize);
601  if (!buf) return NULL;
602  }
603  assert(pos + len < bufSize);
604  memcpy(buf + pos, inputNames[i], len);
605  pos += len;
606  nbFiles++;
607  } else {
608  char* bufend = buf + bufSize;
609  nbFiles += (unsigned)UTIL_prepareFileList(inputNames[i], &buf, &pos, &bufend);
610  if (buf == NULL) return NULL;
611  assert(bufend > buf);
612  bufSize = (size_t)(bufend - buf);
613  } }
614 
615  if (nbFiles == 0) { free(buf); return NULL; }
616 
617  fileTable = (const char**)malloc(((size_t)nbFiles+1) * sizeof(const char*));
618  if (!fileTable) { free(buf); return NULL; }
619 
620  for (i=0, pos=0; i<nbFiles; i++) {
621  fileTable[i] = buf + pos;
622  pos += strlen(fileTable[i]) + 1;
623  }
624 
625  if (pos > bufSize) {
626  free(buf);
627  free((void*)fileTable);
628  return NULL;
629  } /* can this happen ? */
630 
631  *allocatedBuffer = buf;
632  *allocatedNamesNb = nbFiles;
633 
634  return fileTable;
635 }
636 
637 
638 UTIL_STATIC void
639 UTIL_freeFileList(const char** filenameTable, char* allocatedBuffer)
640 {
641  if (allocatedBuffer) free(allocatedBuffer);
642  if (filenameTable) free((void*)filenameTable);
643 }
644 
645 
646 #if defined (__cplusplus)
647 }
648 #endif
649 
650 #endif /* UTIL_H_MODULE */
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
#define S_ISDIR(mode)
Definition: compat.h:187
#define S_ISREG(mode)
Definition: compat.h:191
#define INT_MAX
Definition: cp-demangle.c:131
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
static static fork const void static count static fd const char const char static newpath const char static path const char path
Definition: sflib.h:35
static static fork const void static count static fd const char const char static newpath const char static path chmod
Definition: sflib.h:35
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
const char * filename
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
#define INVALID_HANDLE_VALUE
Definition: iowin32.c:21
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
void * malloc(size_t size)
Definition: malloc.c:123
static static fork const void static count static fd const char const char static newpath char char char static envp time
Definition: sflib.h:42
static stat
Definition: sflib.h:131
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds utime
Definition: sflib.h:57
static static fork const void static count static fd const char static mode const char static pathname const char static path const char static dev const char static group static getpid static getuid void void static data static pause const char static mode static sync const char const char static newpath const char static pathname unsigned long static filedes void static end_data_segment static handler static getegid char static len static pgid const char static path static newfd static getpgrp static euid const sigset_t static mask const char static len const gid_t static list const char const char static newpath const char static library readdir
Definition: sflib.h:120
static const char struct stat static buf struct stat static buf static vhangup int struct rusage static rusage struct sysinfo static info unsigned static __unused struct utsname static buf const char static size const char static name static pid unsigned static persona static fsgid const void static flags const struct iovec static count static fd const void static len static munlockall struct sched_param static p static sched_yield static policy const struct timespec struct timespec static rem uid_t uid_t uid_t static suid struct pollfd unsigned static timeout chown
Definition: sflib.h:210
static void struct sockaddr socklen_t static fromlen static backlog static fork char char char static envp int struct rusage static rusage struct utsname static buf struct sembuf unsigned
Definition: sflib.h:97
UTIL_STATIC U64 UTIL_getSpanTimeMicro(UTIL_time_t clockStart, UTIL_time_t clockEnd)
Definition: util.h:278
UTIL_STATIC int UTIL_isRegFile(const char *infilename)
Definition: util.h:368
#define UTIL_fstat
Definition: util.h:141
UTIL_STATIC U64 UTIL_getOpenFileSize(FILE *file)
Definition: util.h:390
UTIL_STATIC int UTIL_prepareFileList(const char *dirName, char **bufStart, size_t *pos, char **bufEnd)
Definition: util.h:568
unsigned long long U64
Definition: util.h:76
UTIL_STATIC U32 UTIL_isDirectory(const char *infilename)
Definition: util.h:375
#define UTIL_STAT_MODE_ISREG(st_mode)
Definition: util.h:142
UTIL_STATIC void UTIL_freeFileList(const char **filenameTable, char *allocatedBuffer)
Definition: util.h:639
UTIL_STATIC UTIL_time_t UTIL_getTime(void)
Definition: util.h:277
unsigned char BYTE
Definition: util.h:71
signed long long S64
Definition: util.h:77
UTIL_STATIC U64 UTIL_getTotalFileSize(const char **fileNamesTable, unsigned nbFiles)
Definition: util.h:418
signed int S32
Definition: util.h:75
#define UTIL_fileno
Definition: util.h:152
UTIL_STATIC void * UTIL_realloc(void *ptr, size_t size)
Definition: util.h:432
UTIL_STATIC int UTIL_setFileStat(const char *filename, stat_t *statbuf)
Definition: util.h:322
UTIL_STATIC U64 UTIL_clockSpanMicro(UTIL_time_t clockStart)
Definition: util.h:284
#define UTIL_STATIC
Definition: util.h:174
UTIL_STATIC int UTIL_getFileStat(const char *infilename, stat_t *statbuf)
Definition: util.h:354
#define LIST_SIZE_INCREASE
Definition: util.h:158
UTIL_STATIC U64 UTIL_getSpanTimeNano(UTIL_time_t clockStart, UTIL_time_t clockEnd)
Definition: util.h:279
#define UTIL_stat
Definition: util.h:140
UTIL_STATIC const char ** UTIL_createFileList(const char **inputNames, unsigned inputNamesNb, char **allocatedBuffer, unsigned *allocatedNamesNb)
Definition: util.h:584
UTIL_STATIC U64 UTIL_getFileSize(const char *infilename)
Definition: util.h:407
unsigned int U32
Definition: util.h:74
clock_t UTIL_time_t
Definition: util.h:276
#define UTIL_TYPE_stat
Definition: util.h:139
UTIL_STATIC void UTIL_waitForNextTick(void)
Definition: util.h:297
unsigned short U16
Definition: util.h:72
signed short S16
Definition: util.h:73
UTIL_STATIC U64 UTIL_clockSpanNano(UTIL_time_t clockStart)
Definition: util.h:291
unsigned long long U64
Definition: lz4.c:290
unsigned int U32
Definition: lz4.c:288
assert(limit<=UINT32_MAX/2)
int x
Definition: mipsasm.c:20
int n
Definition: mipsasm.c:19
string FILE
Definition: benchmark.py:21
static int
Definition: sfsocketcall.h:114
unsigned short uint16_t
Definition: sftypes.h:30
long int64_t
Definition: sftypes.h:32
int int32_t
Definition: sftypes.h:33
int size_t
Definition: sftypes.h:40
unsigned int uint32_t
Definition: sftypes.h:29
int clock_t
Definition: sftypes.h:43
unsigned long uint64_t
Definition: sftypes.h:28
short int16_t
Definition: sftypes.h:34
unsigned char uint8_t
Definition: sftypes.h:31
int ptrdiff_t
Definition: sftypes.h:68
Definition: sftypes.h:48
Definition: zipcmp.c:77
Definition: gzappend.c:170
Definition: sftypes.h:80
int pos
Definition: main.c:11
bool init
Definition: core.c:77
DWORD * HANDLE
static const z80_opcode fd[]
Definition: z80_tab.h:997