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 #else
11 # include <stdio.h> // for snprintf(), used by inline dlerror()
12 #endif
13 
14 #ifdef _WIN32
15 # ifndef _MSC_VER
16 # define close wsock_close
17 # endif
18 
19 # ifndef NOMINMAX
20 # define NOMINMAX
21 # endif
22 
23 # include <windows.h>
24 
25 # undef DialogBox
26 # undef LoadImage
27 # undef LoadIcon
28 # undef GetObject
29 # undef DrawText
30 # undef CreateDialog
31 # undef CreateFont
32 # undef DeleteFile
33 # undef GetCurrentTime
34 # undef SetJob
35 # undef SendMessage
36 
37 # ifndef _MSC_VER
38 # include <winsock2.h>
39 # include <ws2tcpip.h>
40 # else
41 # include <io.h>
42 # endif
43 
44 # undef close
45 #else
46 # include <sys/time.h> // Mac OS X needs this before sys/resource
47 # include <sys/resource.h> // for setpriority
48 # include <sys/socket.h>
49 # include <sys/wait.h> // For WIFEXITED on Mac OS X
50 #endif
51 
52 #ifdef _WIN32
53 # include <cstdlib> // for rand()
54 # include <ctime>
55 # include <sys/time.h>
56 # include <sys/types.h> // suseconds_t
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  static inline void srandom(unsigned int seed) { qsrand(seed); }
153  static inline long int random(void) { return qrand(); }
154 #endif
155 
156 # define setenv(x, y, z) ::SetEnvironmentVariableA(x, y)
157 # define unsetenv(x) 0
158 
159  inline unsigned sleep(unsigned int x)
160  {
161  Sleep(x * 1000);
162  return 0;
163  }
164 
165  struct statfs {
166  // long f_type; /* type of filesystem */
167  long f_bsize; /* optimal transfer block size */
168  long f_blocks; /* total data blocks in file system */
169  // long f_bfree; /* free blocks in fs */
170  long f_bavail; /* free blocks avail to non-superuser */
171  // long f_files; /* total file nodes in file system */
172  // long f_ffree; /* free file nodes in fs */
173  // long f_fsid; /* file system id */
174  // long f_namelen; /* maximum length of filenames */
175  // long f_spare[6]; /* spare for later */
176  };
177  inline int statfs(const char* path, struct statfs* buffer)
178  {
179  DWORD spc = 0, bps = 0, fc = 0, c = 0;
180 
181  if (buffer && GetDiskFreeSpaceA(path, &spc, &bps, &fc, &c))
182  {
183  buffer->f_bsize = bps;
184  buffer->f_blocks = spc * c;
185  buffer->f_bavail = spc * fc;
186  return 0;
187  }
188 
189  return -1;
190  }
191 #endif
192 
193 #ifdef _WIN32
194 #define lstat stat
195 #define nice(x) ((int)!::SetPriorityClass(\
196  ::GetCurrentProcess(), ((x) < -10) ? \
197  HIGH_PRIORITY_CLASS : (((x) < 0) ? \
198  ABOVE_NORMAL_PRIORITY_CLASS : (((x) > 10) ? \
199  IDLE_PRIORITY_CLASS : (((x) > 0) ? \
200  BELOW_NORMAL_PRIORITY_CLASS : \
201  NORMAL_PRIORITY_CLASS)))))
202 #define PRIO_PROCESS 0
203 #define setpriority(x, y, z) ((x) == PRIO_PROCESS && y == 0 ? nice(z) : -1)
204 #endif // _WIN32
205 
206 #ifdef _MSC_VER
207 # define SIGTRAP SIGBREAK
208 # define STDERR_FILENO (int)GetStdHandle( STD_ERROR_HANDLE )
209 #endif
210 
211 #ifdef _WIN32
212  //signals: not tested
213 # define SIGHUP 1
214 # define SIGQUIT 3
215 # define SIGKILL 9
216 # define SIGUSR1 10 // used to force UPnP mediamap rebuild in the backend
217 # define SIGUSR2 12 // used to restart LIRC as required
218 # define SIGPIPE 13 // not implemented in MINGW, will produce "unable to ignore sigpipe"
219 # define SIGALRM 14
220 # define SIGCONT 18
221 # define SIGSTOP 19
222 
223 # define S_IRGRP 0
224 # define S_IROTH 0
225 # define O_SYNC 0
226 
227  #define mkfifo(path, mode) \
228  (int)CreateNamedPipeA(path, PIPE_ACCESS_DUPLEX | WRITE_DAC, \
229  PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, \
230  1024, 1024, 10000, nullptr)
231 
232 # define RTLD_LAZY 0
233 # define dlopen(x, y) LoadLibraryA((x))
234 # define dlclose(x) !FreeLibrary((HMODULE)(x))
235 # define dlsym(x, y) GetProcAddress((HMODULE)(x), (y))
236 
237 # ifdef __cplusplus
238  inline const char *dlerror(void)
239  {
240  #define DLERR_MAX 512
241  static char errStr[DLERR_MAX];
242  DWORD errCode = GetLastError();
243 
244  if (!FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
245  FORMAT_MESSAGE_IGNORE_INSERTS |
246  FORMAT_MESSAGE_MAX_WIDTH_MASK,
247  nullptr, errCode,
248  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
249  errStr, DLERR_MAX - 1, nullptr))
250  snprintf(errStr, DLERR_MAX - 1,
251  "dlopen()/dlsym() caused error %d", (int)errCode);
252 
253  return errStr;
254  }
255 # else // __cplusplus
256 # define dlerror() "dlerror() is unimplemented."
257 # endif // __cplusplus
258 
259  // getuid/geteuid/setuid - not implemented
260 # define getuid() 0
261 # define geteuid() 0
262 # define setuid(x) 0
263 # define seteuid(x) 0
264 #endif // _WIN32
265 
266 #if defined(_WIN32) && !defined(gmtime_r)
267 // FFmpeg libs already have a workaround, use it if the headers are included,
268 // use this otherwise.
269 static __inline struct tm *gmtime_r(const time_t *timep, struct tm *result)
270 {
271  // this is safe on windows, where gmtime uses a thread local variable.
272  // using _gmtime_s() would be better, but needs to be tested on windows.
273  struct tm *tmp = gmtime(timep);
274  if (tmp)
275  {
276  *result = *tmp;
277  return result;
278  }
279  return nullptr;
280 }
281 #endif
282 
283 #if defined(_WIN32) && !defined(localtime_r)
284 // FFmpeg libs already have a workaround, use it if the headers are included,
285 // use this otherwise.
286 static __inline struct tm *localtime_r(const time_t *timep, struct tm *result)
287 {
288  // this is safe, windows uses a thread local variable for localtime().
289  if (timep && result)
290  {
291  struct tm *win_tmp = localtime(timep);
292  memcpy(result, win_tmp, sizeof(struct tm));
293  return result;
294  }
295  return nullptr;
296 }
297 #endif
298 
299 #ifdef _WIN32
300 # define timeradd(a, b, result) \
301  do { \
302  (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \
303  (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \
304  if ((result)->tv_usec >= 1000000) \
305  { \
306  ++(result)->tv_sec; \
307  (result)->tv_usec -= 1000000; \
308  } \
309  } while (0)
310 # define timersub(a, b, result) \
311  do { \
312  (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
313  (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
314  if ((result)->tv_usec < 0) { \
315  --(result)->tv_sec; \
316  (result)->tv_usec += 1000000; \
317  } \
318  } while (0)
319 
320 // TODO this stuff is not implemented yet
321 # define daemon(x, y) -1
322 # define getloadavg(x, y) -1
323 
324 // this stuff is untested
325 # define WIFEXITED(w) (((w) & 0xff) == 0)
326 # define WIFSIGNALED(w) (((w) & 0x7f) > 0 && (((w) & 0x7f) < 0x7f))
327 # define WIFSTOPPED(w) (((w) & 0xff) == 0x7f)
328 # define WEXITSTATUS(w) (((w) >> 8) & 0xff)
329 # define WTERMSIG(w) ((w) & 0x7f)
330 
331  using suseconds_t = long;
332 
333 #endif // _WIN32
334 
335 #include <sys/param.h> // Defines BSD on FreeBSD, Mac OS X
336 
337 #include "mythconfig.h"
338 
339 #if CONFIG_DARWIN && ! defined (_SUSECONDS_T)
340  using suseconds_t = int32_t; // 10.3 or earlier don't have this
341 #endif
342 
343 // Libdvdnav now uses off64_t lseek64(), which BSD/Darwin doesn't have.
344 // Luckily, its lseek() is already 64bit compatible
345 #ifdef BSD
346  typedef off_t off64_t; //NOLINT(modernize-use-using)included from C code
347  #define lseek64(f,o,w) lseek(f,o,w)
348 #endif
349 
350 #if defined(_MSC_VER)
351 #include <sys/stat.h> // S_IREAD/WRITE on MinGW
352 # define S_IRUSR _S_IREAD
353 # ifndef lseek64
354 # define lseek64( f, o, w ) _lseeki64( f, o, w )
355 # endif
356 #endif
357 
358 #ifdef _WIN32
359 # define fseeko(stream, offset, whence) fseeko64(stream, offset, whence)
360 # define ftello(stream) ftello64(stream)
361 #endif
362 
363 #if defined(USING_MINGW) && defined(FILENAME_MAX)
364 # include <cerrno>
365 # include <cstddef>
366 # include <cstring>
367 # include <dirent.h>
368  static inline int readdir_r(
369  DIR *dirp, struct dirent *entry, struct dirent **result)
370  {
371  errno = 0;
372  struct dirent *tmp = readdir(dirp);
373  if (tmp && entry)
374  {
375  int offset = offsetof(struct dirent, d_name);
376  memcpy(entry, tmp, offset);
377  strncpy(entry->d_name, tmp->d_name, FILENAME_MAX);
378  tmp->d_name[strlen(entry->d_name)] = '\0';
379  if (result)
380  *result = entry;
381  return 0;
382  }
383  else
384  {
385  if (result)
386  *result = nullptr;
387  return errno;
388  }
389  }
390 #endif
391 
392 #ifdef _WIN32
393 # define PREFIX64 "I64"
394 #else
395 # define PREFIX64 "ll"
396 #endif
397 
398 #ifdef ANDROID
399 #ifndef S_IREAD
400 #define S_IREAD S_IRUSR
401 #endif
402 #ifndef S_IWRITE
403 #define S_IWRITE S_IRUSR
404 #endif
405 #endif
406 
407 #ifdef _WIN32
408 # ifdef LZO_COMPILE_TIME_ASSERT_HEADER
409 # undef LZO_COMPILE_TIME_ASSERT_HEADER
410 # endif
411 
412 # define LZO_COMPILE_TIME_ASSERT_HEADER( a )
413 
414 # ifdef LZO_COMPILE_TIME_ASSERT
415 # undef LZO_COMPILE_TIME_ASSERT
416 # endif
417 
418 # define LZO_COMPILE_TIME_ASSERT( a )
419 #endif
420 
421 #endif // __COMPAT_H__
static __inline struct tm * gmtime_r(const time_t *timep, struct tm *result)
Definition: compat.h:269
const char * dlerror(void)
Definition: compat.h:238
static __inline struct tm * localtime_r(const time_t *timep, struct tm *result)
Definition: compat.h:286
long f_bavail
Definition: compat.h:170
static guint32 * tmp
Definition: goom_core.c:35
unsigned sleep(unsigned int x)
Definition: compat.h:159
#define off_t
int statfs(const char *path, struct statfs *buffer)
Definition: compat.h:177
Definition: compat.h:165
unsigned int uint
Definition: compat.h:140
#define DLERR_MAX
long f_blocks
Definition: compat.h:168
long suseconds_t
Definition: compat.h:331
long f_bsize
Definition: compat.h:167
static long int random(void)
Definition: compat.h:149
static void srandom(unsigned int)
Definition: compat.h:148