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