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