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