MythTV  master
compat.h
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 // Simple header which encapsulates platform incompatibilities, so we
3 // do not need to litter the codebase with ifdefs.
4 
5 #ifndef COMPAT_H
6 #define COMPAT_H
7 
8 #ifdef __cplusplus
9 # include <cstdio> // for snprintf(), used by inline dlerror()
10 # include <QtGlobal> // for Q_OS_XXX
11 #else
12 # include <stdio.h> // for snprintf(), used by inline dlerror()
13 #endif
14 
15 #ifdef _WIN32
16 # ifndef _MSC_VER
17 # define close wsock_close
18 # endif
19 
20 # ifndef NOMINMAX
21 # define NOMINMAX
22 # endif
23 
24 # include <windows.h>
25 
26 # undef DialogBox
27 # undef LoadImage
28 # undef LoadIcon
29 # undef GetObject
30 # undef DrawText
31 # undef CreateDialog
32 # undef CreateFont
33 # undef DeleteFile
34 # undef GetCurrentTime
35 # undef SetJob
36 # undef SendMessage
37 
38 # ifndef _MSC_VER
39 # include <winsock2.h>
40 # include <ws2tcpip.h>
41 # else
42 # include <io.h>
43 # endif
44 
45 # undef close
46 #else
47 # include <sys/time.h> // Mac OS X needs this before sys/resource
48 # include <sys/resource.h> // for setpriority
49 # include <sys/socket.h>
50 # include <sys/wait.h> // For WIFEXITED on Mac OS X
51 #endif
52 
53 #ifdef _WIN32
54 # include <cstdlib> // for rand()
55 # include <ctime>
56 # include <sys/time.h>
57 # include <sys/types.h> // suseconds_t
58 #endif
59 
60 #ifdef _MSC_VER
61  // Turn off the visual studio warnings (identifier was truncated)
62  #pragma warning(disable:4786)
63 
64  #ifdef restrict
65  #undef restrict
66  #endif
67 
68  #include <cinttypes>
69  #include <direct.h>
70  #include <process.h>
71 
72  #define strtoll _strtoi64
73  #define strncasecmp _strnicmp
74  #define snprintf _snprintf
75 
76  #ifdef _WIN64
77  using ssize_t = __int64;
78  #else
79  using ssize_t = int;
80  #endif
81 
82  // Check for execute, only checking existance in MSVC
83  #define X_OK 0
84 
85  #if (_MSC_VER < 1800)
86  #define rint( x ) floor(x + 0.5)
87  #define round( x ) floor(x + 0.5)
88 
89  #if ( _MSC_VER < 1700)
90  #define signbit( x ) ( x < 0 )
91  #endif
92 
93  #undef M_PI
94  #define M_PI 3.14159265358979323846
95  #endif
96 
97  #define getpid() _getpid()
98  #define ftruncate( fd, fsize ) _chsize( fd, fsize )
99 
100  #ifndef S_ISCHR
101  # ifdef S_IFCHR
102  # define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
103  # else
104  # define S_ISCHR(m) 0
105  # endif
106  #endif /* !S_ISCHR */
107 
108  #ifndef S_ISBLK
109  # define S_ISBLK(m) 0
110  #endif
111 
112  #ifndef S_ISREG
113  # define S_ISREG(m) 1
114  #endif
115 
116  #ifndef S_ISDIR
117  # ifdef S_IFDIR
118  # define S_ISDIR(m) (((m) & S_IFDIR) == S_IFDIR )
119  # else
120  # define S_ISDIR(m) 0
121  # endif
122  #endif
123 
124  using mode_t = uint32_t;
125 
126  #if !defined(__cplusplus) && !defined( inline )
127  # define inline __inline
128  #endif
129 
130  #if !defined(__func__) // C99 & C++11
131  # define __func__ __FUNCTION__
132  #endif
133 
134 #endif
135 
136 #ifdef _WIN32
137 # define fsync(FD) 0
138 //used in videodevice only - that code is not windows-compatible anyway
139 # define minor(X) 0
140 
141  using uint = unsigned int;
142 #endif
143 
144 #if defined(__cplusplus) && defined(_WIN32)
145 # include <QtGlobal>
146 
147 #if QT_VERSION >= QT_VERSION_CHECK(5,10,0)
148  #include <QRandomGenerator>
149  static inline void srandom(unsigned int /*seed*/) { }
150  static inline long int random(void)
151  { return QRandomGenerator::global()->generate64(); }
152 #else
153  // cppcheck-suppress qsrandCalled
154  static inline void srandom(unsigned int seed) { qsrand(seed); }
155  static inline long int random(void) { return qrand(); }
156 #endif
157 
158 # define setenv(x, y, z) ::SetEnvironmentVariableA(x, y)
159 # define unsetenv(x) 0
160 
161  inline unsigned sleep(unsigned int x)
162  {
163  Sleep(x * 1000);
164  return 0;
165  }
166 
167  struct statfs {
168  // long f_type; /* type of filesystem */
169  long f_bsize; /* optimal transfer block size */
170  long f_blocks; /* total data blocks in file system */
171  // long f_bfree; /* free blocks in fs */
172  long f_bavail; /* free blocks avail to non-superuser */
173  // long f_files; /* total file nodes in file system */
174  // long f_ffree; /* free file nodes in fs */
175  // long f_fsid; /* file system id */
176  // long f_namelen; /* maximum length of filenames */
177  // long f_spare[6]; /* spare for later */
178  };
179  inline int statfs(const char* path, struct statfs* buffer)
180  {
181  DWORD spc = 0, bps = 0, fc = 0, c = 0;
182 
183  if (buffer && GetDiskFreeSpaceA(path, &spc, &bps, &fc, &c))
184  {
185  buffer->f_bsize = bps;
186  buffer->f_blocks = spc * c;
187  buffer->f_bavail = spc * fc;
188  return 0;
189  }
190 
191  return -1;
192  }
193 #endif
194 
195 #ifdef _WIN32
196 #define lstat stat
197 #define nice(x) ((int)!::SetPriorityClass(\
198  ::GetCurrentProcess(), ((x) < -10) ? \
199  HIGH_PRIORITY_CLASS : (((x) < 0) ? \
200  ABOVE_NORMAL_PRIORITY_CLASS : (((x) > 10) ? \
201  IDLE_PRIORITY_CLASS : (((x) > 0) ? \
202  BELOW_NORMAL_PRIORITY_CLASS : \
203  NORMAL_PRIORITY_CLASS)))))
204 #define PRIO_PROCESS 0
205 #define setpriority(x, y, z) ((x) == PRIO_PROCESS && y == 0 ? nice(z) : -1)
206 #endif // _WIN32
207 
208 #ifdef _MSC_VER
209 # define SIGTRAP SIGBREAK
210 # define STDERR_FILENO (int)GetStdHandle( STD_ERROR_HANDLE )
211 #endif
212 
213 #ifdef _WIN32
214  //signals: not tested
215 # define SIGHUP 1
216 # define SIGQUIT 3
217 # define SIGKILL 9
218 # define SIGUSR1 10 // used to force UPnP mediamap rebuild in the backend
219 # define SIGUSR2 12 // used to restart LIRC as required
220 # define SIGPIPE 13 // not implemented in MINGW, will produce "unable to ignore sigpipe"
221 # define SIGALRM 14
222 # define SIGCONT 18
223 # define SIGSTOP 19
224 
225 # define S_IRGRP 0
226 # define S_IROTH 0
227 # define O_SYNC 0
228 
229  #define mkfifo(path, mode) \
230  (int)CreateNamedPipeA(path, PIPE_ACCESS_DUPLEX | WRITE_DAC, \
231  PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, \
232  1024, 1024, 10000, nullptr)
233 
234 # define RTLD_LAZY 0
235 # define dlopen(x, y) LoadLibraryA((x))
236 # define dlclose(x) !FreeLibrary((HMODULE)(x))
237 # define dlsym(x, y) GetProcAddress((HMODULE)(x), (y))
238 
239 # ifdef __cplusplus
240  inline const char *dlerror(void)
241  {
242  #define DLERR_MAX 512
243  static char errStr[DLERR_MAX];
244  DWORD errCode = GetLastError();
245 
246  if (!FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
247  FORMAT_MESSAGE_IGNORE_INSERTS |
248  FORMAT_MESSAGE_MAX_WIDTH_MASK,
249  nullptr, errCode,
250  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
251  errStr, DLERR_MAX - 1, nullptr))
252  snprintf(errStr, DLERR_MAX - 1,
253  "dlopen()/dlsym() caused error %d", (int)errCode);
254 
255  return errStr;
256  }
257 # else // __cplusplus
258 # define dlerror() "dlerror() is unimplemented."
259 # endif // __cplusplus
260 
261  // getuid/geteuid/setuid - not implemented
262 # define getuid() 0
263 # define geteuid() 0
264 # define setuid(x) 0
265 # define seteuid(x) 0
266 #endif // _WIN32
267 
268 #if defined(_WIN32) && !defined(gmtime_r)
269 // FFmpeg libs already have a workaround, use it if the headers are included,
270 // use this otherwise.
271 static __inline struct tm *gmtime_r(const time_t *timep, struct tm *result)
272 {
273  // this is safe on windows, where gmtime uses a thread local variable.
274  // using _gmtime_s() would be better, but needs to be tested on windows.
275  struct tm *tmp = gmtime(timep);
276  if (tmp)
277  {
278  *result = *tmp;
279  return result;
280  }
281  return nullptr;
282 }
283 #endif
284 
285 #if defined(_WIN32) && !defined(localtime_r)
286 // FFmpeg libs already have a workaround, use it if the headers are included,
287 // use this otherwise.
288 static __inline struct tm *localtime_r(const time_t *timep, struct tm *result)
289 {
290  // this is safe, windows uses a thread local variable for localtime().
291  if (timep && result)
292  {
293  struct tm *win_tmp = localtime(timep);
294  memcpy(result, win_tmp, sizeof(struct tm));
295  return result;
296  }
297  return nullptr;
298 }
299 #endif
300 
301 #ifdef _WIN32
302 # define timeradd(a, b, result) \
303  do { \
304  (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \
305  (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \
306  if ((result)->tv_usec >= 1000000) \
307  { \
308  ++(result)->tv_sec; \
309  (result)->tv_usec -= 1000000; \
310  } \
311  } while (0)
312 # define timersub(a, b, result) \
313  do { \
314  (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
315  (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
316  if ((result)->tv_usec < 0) { \
317  --(result)->tv_sec; \
318  (result)->tv_usec += 1000000; \
319  } \
320  } while (0)
321 
322 // TODO this stuff is not implemented yet
323 # define daemon(x, y) -1
324 # define getloadavg(x, y) -1
325 
326 // this stuff is untested
327 # define WIFEXITED(w) (((w) & 0xff) == 0)
328 # define WIFSIGNALED(w) (((w) & 0x7f) > 0 && (((w) & 0x7f) < 0x7f))
329 # define WIFSTOPPED(w) (((w) & 0xff) == 0x7f)
330 # define WEXITSTATUS(w) (((w) >> 8) & 0xff)
331 # define WTERMSIG(w) ((w) & 0x7f)
332 
333  using suseconds_t = long;
334 
335 #endif // _WIN32
336 
337 #include <sys/param.h> // Defines BSD on FreeBSD, Mac OS X
338 
339 #include "mythconfig.h"
340 
341 #if CONFIG_DARWIN && ! defined (_SUSECONDS_T)
342  using suseconds_t = int32_t; // 10.3 or earlier don't have this
343 #endif
344 
345 // Libdvdnav now uses off64_t lseek64(), which BSD/Darwin doesn't have.
346 // Luckily, its lseek() is already 64bit compatible
347 #ifdef BSD
348  typedef off_t off64_t; //NOLINT(modernize-use-using) included from dvdnav C code
349  #define lseek64(f,o,w) lseek(f,o,w)
350 #endif
351 
352 #if defined(_MSC_VER)
353 #include <sys/stat.h> // S_IREAD/WRITE on MinGW
354 # define S_IRUSR _S_IREAD
355 # ifndef lseek64
356 # define lseek64( f, o, w ) _lseeki64( f, o, w )
357 # endif
358 #endif
359 
360 #ifdef _WIN32
361 # define fseeko(stream, offset, whence) fseeko64(stream, offset, whence)
362 # define ftello(stream) ftello64(stream)
363 #endif
364 
365 #if defined(USING_MINGW) && defined(FILENAME_MAX)
366 # include <cerrno>
367 # include <cstddef>
368 # include <cstring>
369 # include <dirent.h>
370  static inline int readdir_r(
371  DIR *dirp, struct dirent *entry, struct dirent **result)
372  {
373  errno = 0;
374  struct dirent *tmp = readdir(dirp);
375  if (tmp && entry)
376  {
377  int offset = offsetof(struct dirent, d_name);
378  memcpy(entry, tmp, offset);
379  strncpy(entry->d_name, tmp->d_name, FILENAME_MAX);
380  tmp->d_name[strlen(entry->d_name)] = '\0';
381  if (result)
382  *result = entry;
383  return 0;
384  }
385  else
386  {
387  if (result)
388  *result = nullptr;
389  return errno;
390  }
391  }
392 #endif
393 
394 #ifdef Q_OS_ANDROID
395 #ifndef S_IREAD
396 #define S_IREAD S_IRUSR
397 #endif
398 #ifndef S_IWRITE
399 #define S_IWRITE S_IRUSR
400 #endif
401 #endif
402 
403 #ifdef _WIN32
404 # ifdef LZO_COMPILE_TIME_ASSERT_HEADER
405 # undef LZO_COMPILE_TIME_ASSERT_HEADER
406 # endif
407 
408 # define LZO_COMPILE_TIME_ASSERT_HEADER( a )
409 
410 # ifdef LZO_COMPILE_TIME_ASSERT
411 # undef LZO_COMPILE_TIME_ASSERT
412 # endif
413 
414 # define LZO_COMPILE_TIME_ASSERT( a )
415 #endif
416 
417 #endif // COMPAT_H
srandom
static void srandom(unsigned int)
Definition: compat.h:149
tmp
static guint32 * tmp
Definition: goom_core.cpp:31
sleep
unsigned sleep(unsigned int x)
Definition: compat.h:161
statfs
int statfs(const char *path, struct statfs *buffer)
Definition: compat.h:179
hardwareprofile.smolt.long
long
Definition: smolt.py:76
dlerror
const char * dlerror(void)
Definition: compat.h:240
uint
unsigned int uint
Definition: compat.h:141
off_t
#define off_t
Definition: mythiowrapper.cpp:238
statfs::f_blocks
long f_blocks
Definition: compat.h:170
random
static long int random(void)
Definition: compat.h:150
statfs
Definition: compat.h:167
statfs::f_bsize
long f_bsize
Definition: compat.h:169
gmtime_r
static __inline struct tm * gmtime_r(const time_t *timep, struct tm *result)
Definition: compat.h:271
DLERR_MAX
#define DLERR_MAX
suseconds_t
long suseconds_t
Definition: compat.h:333
statfs::f_bavail
long f_bavail
Definition: compat.h:172
localtime_r
static __inline struct tm * localtime_r(const time_t *timep, struct tm *result)
Definition: compat.h:288