0001-Fix-file_Emu-on-musl.patch 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. From 7ae4fcf290ffb0b76374efafeaee575456ac9023 Mon Sep 17 00:00:00 2001
  2. From: Khem Raj <raj.khem@gmail.com>
  3. Date: Sun, 6 Nov 2016 23:08:27 -0800
  4. Subject: [PATCH 01/10] Fix file_Emu on musl
  5. Signed-off-by: Khem Raj <raj.khem@gmail.com>
  6. ---
  7. xbmc/cores/DllLoader/exports/emu_msvcrt.cpp | 28 ++--
  8. xbmc/cores/DllLoader/exports/emu_msvcrt.h | 2 +-
  9. .../DllLoader/exports/util/EmuFileWrapper.cpp | 172 +++++++++------------
  10. xbmc/cores/DllLoader/exports/util/EmuFileWrapper.h | 27 ++--
  11. xbmc/cores/DllLoader/exports/wrapper.c | 4 +-
  12. 5 files changed, 99 insertions(+), 134 deletions(-)
  13. diff --git a/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp b/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp
  14. index ab14942..a39014a 100644
  15. --- a/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp
  16. +++ b/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp
  17. @@ -51,6 +51,7 @@
  18. #include <fcntl.h>
  19. #include <time.h>
  20. #include <signal.h>
  21. +#include <paths.h>
  22. #ifdef TARGET_POSIX
  23. #include "PlatformDefs.h" // for __stat64
  24. #include "XFileUtils.h"
  25. @@ -476,13 +477,10 @@ extern "C"
  26. EmuFileObject* o = g_emuFileWrapper.GetFileObjectByDescriptor(fd);
  27. if (o)
  28. {
  29. - if(!o->used)
  30. - return NULL;
  31. -
  32. int nmode = convert_fmode(mode);
  33. if( (o->mode & nmode) != nmode)
  34. CLog::Log(LOGWARNING, "dll_fdopen - mode 0x%x differs from fd mode 0x%x", nmode, o->mode);
  35. - return &o->file_emu;
  36. + return g_emuFileWrapper.GetStreamByFileObject(o);
  37. }
  38. else if (!IS_STD_DESCRIPTOR(fd))
  39. {
  40. @@ -545,7 +543,7 @@ extern "C"
  41. return -1;
  42. }
  43. object->mode = iMode;
  44. - return g_emuFileWrapper.GetDescriptorByStream(&object->file_emu);
  45. + return g_emuFileWrapper.GetDescriptorByFileObject(object);
  46. }
  47. delete pFile;
  48. return -1;
  49. @@ -1214,8 +1212,8 @@ extern "C"
  50. {
  51. FILE* file = NULL;
  52. #if defined(TARGET_LINUX) && !defined(TARGET_ANDROID)
  53. - if (strcmp(filename, MOUNTED) == 0
  54. - || strcmp(filename, MNTTAB) == 0)
  55. + if (strcmp(filename, _PATH_MOUNTED) == 0
  56. + || strcmp(filename, _PATH_MNTTAB) == 0)
  57. {
  58. CLog::Log(LOGINFO, "%s - something opened the mount file, let's hope it knows what it's doing", __FUNCTION__);
  59. return fopen(filename, mode);
  60. @@ -1622,7 +1620,7 @@ extern "C"
  61. int ret;
  62. ret = dll_fgetpos64(stream, &tmpPos);
  63. -#if !defined(TARGET_POSIX) || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID)
  64. +#if !defined(__GLIBC__) || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID)
  65. *pos = (fpos_t)tmpPos;
  66. #else
  67. pos->__pos = (off_t)tmpPos.__pos;
  68. @@ -1635,8 +1633,9 @@ extern "C"
  69. CFile* pFile = g_emuFileWrapper.GetFileXbmcByStream(stream);
  70. if (pFile != NULL)
  71. {
  72. -#if !defined(TARGET_POSIX) || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID)
  73. - *pos = pFile->GetPosition();
  74. +#if !defined(__GLIBC__) || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID)
  75. + uint64_t *ppos = (uint64_t *) pos;
  76. + *ppos = pFile->GetPosition();
  77. #else
  78. pos->__pos = pFile->GetPosition();
  79. #endif
  80. @@ -1657,8 +1656,9 @@ extern "C"
  81. int fd = g_emuFileWrapper.GetDescriptorByStream(stream);
  82. if (fd >= 0)
  83. {
  84. -#if !defined(TARGET_POSIX) || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID)
  85. - if (dll_lseeki64(fd, *pos, SEEK_SET) >= 0)
  86. +#if !defined(__GLIBC__) || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID)
  87. + const uint64_t *ppos = (const uint64_t *) pos;
  88. + if (dll_lseeki64(fd, *ppos, SEEK_SET) >= 0)
  89. #else
  90. if (dll_lseeki64(fd, (__off64_t)pos->__pos, SEEK_SET) >= 0)
  91. #endif
  92. @@ -1674,7 +1674,7 @@ extern "C"
  93. {
  94. // it might be something else than a file, or the file is not emulated
  95. // let the operating system handle it
  96. -#if !defined(TARGET_POSIX) || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID)
  97. +#if !defined(__GLIBC__) || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID)
  98. return fsetpos(stream, pos);
  99. #else
  100. return fsetpos64(stream, pos);
  101. @@ -1690,7 +1690,7 @@ extern "C"
  102. if (fd >= 0)
  103. {
  104. fpos64_t tmpPos;
  105. -#if !defined(TARGET_POSIX) || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID)
  106. +#if !defined(__GLIBC__) || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID)
  107. tmpPos= *pos;
  108. #else
  109. tmpPos.__pos = (off64_t)(pos->__pos);
  110. diff --git a/xbmc/cores/DllLoader/exports/emu_msvcrt.h b/xbmc/cores/DllLoader/exports/emu_msvcrt.h
  111. index 3294d9a..c7c483f 100644
  112. --- a/xbmc/cores/DllLoader/exports/emu_msvcrt.h
  113. +++ b/xbmc/cores/DllLoader/exports/emu_msvcrt.h
  114. @@ -24,7 +24,7 @@
  115. #define _onexit_t void*
  116. #endif
  117. -#if defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID)
  118. +#if defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID) || !defined(__GLIBC__)
  119. typedef off_t __off_t;
  120. typedef int64_t off64_t;
  121. typedef off64_t __off64_t;
  122. diff --git a/xbmc/cores/DllLoader/exports/util/EmuFileWrapper.cpp b/xbmc/cores/DllLoader/exports/util/EmuFileWrapper.cpp
  123. index 8927d41..e9a2ab0 100644
  124. --- a/xbmc/cores/DllLoader/exports/util/EmuFileWrapper.cpp
  125. +++ b/xbmc/cores/DllLoader/exports/util/EmuFileWrapper.cpp
  126. @@ -52,16 +52,7 @@ constexpr bool isValidFilePtr(FILE* f)
  127. }
  128. CEmuFileWrapper::CEmuFileWrapper()
  129. {
  130. - // since we always use dlls we might just initialize it directly
  131. - for (int i = 0; i < MAX_EMULATED_FILES; i++)
  132. - {
  133. - memset(&m_files[i], 0, sizeof(EmuFileObject));
  134. - m_files[i].used = false;
  135. -#if defined(TARGET_WINDOWS) && (_MSC_VER >= 1900)
  136. - m_files[i].file_emu._Placeholder = new kodi_iobuf();
  137. -#endif
  138. - FileDescriptor(m_files[i].file_emu)->_file = -1;
  139. - }
  140. + memset(m_files, 0, sizeof(m_files));
  141. }
  142. CEmuFileWrapper::~CEmuFileWrapper()
  143. @@ -73,29 +64,7 @@ void CEmuFileWrapper::CleanUp()
  144. {
  145. CSingleLock lock(m_criticalSection);
  146. for (int i = 0; i < MAX_EMULATED_FILES; i++)
  147. - {
  148. - if (m_files[i].used)
  149. - {
  150. - m_files[i].file_xbmc->Close();
  151. - delete m_files[i].file_xbmc;
  152. -
  153. - if (m_files[i].file_lock)
  154. - {
  155. - delete m_files[i].file_lock;
  156. - m_files[i].file_lock = nullptr;
  157. - }
  158. -#if !defined(TARGET_WINDOWS)
  159. - //Don't memset on Windows as it overwrites our pointer
  160. - memset(&m_files[i], 0, sizeof(EmuFileObject));
  161. -#endif
  162. - m_files[i].used = false;
  163. - FileDescriptor(m_files[i].file_emu)->_file = -1;
  164. - }
  165. -#if defined(TARGET_WINDOWS) && (_MSC_VER >= 1900)
  166. - delete static_cast<kodi_iobuf*>(m_files[i].file_emu._Placeholder);
  167. - m_files[i].file_emu._Placeholder = nullptr;
  168. -#endif
  169. - }
  170. + UnRegisterFileObject(&m_files[i], true);
  171. }
  172. EmuFileObject* CEmuFileWrapper::RegisterFileObject(XFILE::CFile* pFile)
  173. @@ -106,13 +75,11 @@ EmuFileObject* CEmuFileWrapper::RegisterFileObject(XFILE::CFile* pFile)
  174. for (int i = 0; i < MAX_EMULATED_FILES; i++)
  175. {
  176. - if (!m_files[i].used)
  177. + if (!m_files[i].file_xbmc)
  178. {
  179. // found a free location
  180. object = &m_files[i];
  181. - object->used = true;
  182. object->file_xbmc = pFile;
  183. - FileDescriptor(object->file_emu)->_file = (i + FILE_WRAPPER_OFFSET);
  184. object->file_lock = new CCriticalSection();
  185. break;
  186. }
  187. @@ -121,82 +88,74 @@ EmuFileObject* CEmuFileWrapper::RegisterFileObject(XFILE::CFile* pFile)
  188. return object;
  189. }
  190. -void CEmuFileWrapper::UnRegisterFileObjectByDescriptor(int fd)
  191. +void CEmuFileWrapper::UnRegisterFileObject(EmuFileObject *object, bool free_file)
  192. +
  193. {
  194. - int i = fd - FILE_WRAPPER_OFFSET;
  195. - if (! (i >= 0 && i < MAX_EMULATED_FILES))
  196. - return;
  197. + if (object && object->file_xbmc)
  198. + {
  199. + if (object->file_xbmc && free_file)
  200. + {
  201. + object->file_xbmc->Close();
  202. + delete object->file_xbmc;
  203. + }
  204. + if (object->file_lock)
  205. + {
  206. + delete object->file_lock;
  207. + }
  208. - if (!m_files[i].used)
  209. - return;
  210. + memset(object, 0, sizeof(*object));
  211. + }
  212. +}
  213. +void CEmuFileWrapper::UnRegisterFileObjectByDescriptor(int fd)
  214. +{
  215. CSingleLock lock(m_criticalSection);
  216. -
  217. - // we assume the emulated function alreay deleted the CFile object
  218. - if (m_files[i].file_lock)
  219. - {
  220. - delete m_files[i].file_lock;
  221. - m_files[i].file_lock = nullptr;
  222. - }
  223. -#if !defined(TARGET_WINDOWS)
  224. - //Don't memset on Windows as it overwrites our pointer
  225. - memset(&m_files[i], 0, sizeof(EmuFileObject));
  226. -#endif
  227. - m_files[i].used = false;
  228. - FileDescriptor(m_files[i].file_emu)->_file = -1;
  229. + UnRegisterFileObject(GetFileObjectByDescriptor(fd), false);
  230. }
  231. void CEmuFileWrapper::UnRegisterFileObjectByStream(FILE* stream)
  232. {
  233. if (isValidFilePtr(stream))
  234. {
  235. - return UnRegisterFileObjectByDescriptor(FileDescriptor(*stream)->_file);
  236. + CSingleLock lock(m_criticalSection);
  237. + UnRegisterFileObject(GetFileObjectByStream(stream), false);
  238. }
  239. }
  240. void CEmuFileWrapper::LockFileObjectByDescriptor(int fd)
  241. {
  242. - int i = fd - FILE_WRAPPER_OFFSET;
  243. - if (i >= 0 && i < MAX_EMULATED_FILES)
  244. + EmuFileObject* object = GetFileObjectByDescriptor(fd);
  245. + if (object && object->file_xbmc)
  246. {
  247. - if (m_files[i].used)
  248. - {
  249. - m_files[i].file_lock->lock();
  250. - }
  251. + object->file_lock->lock();
  252. }
  253. }
  254. bool CEmuFileWrapper::TryLockFileObjectByDescriptor(int fd)
  255. {
  256. - int i = fd - FILE_WRAPPER_OFFSET;
  257. - if (i >= 0 && i < MAX_EMULATED_FILES)
  258. + EmuFileObject* object = GetFileObjectByDescriptor(fd);
  259. + if (object && object->file_xbmc)
  260. {
  261. - if (m_files[i].used)
  262. - {
  263. - return m_files[i].file_lock->try_lock();
  264. - }
  265. + return object->file_lock->try_lock();
  266. }
  267. return false;
  268. }
  269. void CEmuFileWrapper::UnlockFileObjectByDescriptor(int fd)
  270. {
  271. - int i = fd - FILE_WRAPPER_OFFSET;
  272. - if (i >= 0 && i < MAX_EMULATED_FILES)
  273. + EmuFileObject* object = GetFileObjectByDescriptor(fd);
  274. + if (object && object->file_xbmc)
  275. {
  276. - if (m_files[i].used)
  277. - {
  278. - m_files[i].file_lock->unlock();
  279. - }
  280. + object->file_lock->unlock();
  281. }
  282. }
  283. EmuFileObject* CEmuFileWrapper::GetFileObjectByDescriptor(int fd)
  284. {
  285. - int i = fd - FILE_WRAPPER_OFFSET;
  286. + int i = fd - 0x7000000;
  287. if (i >= 0 && i < MAX_EMULATED_FILES)
  288. {
  289. - if (m_files[i].used)
  290. + if (m_files[i].file_xbmc)
  291. {
  292. return &m_files[i];
  293. }
  294. @@ -204,20 +163,39 @@ EmuFileObject* CEmuFileWrapper::GetFileObjectByDescriptor(int fd)
  295. return nullptr;
  296. }
  297. +int CEmuFileWrapper::GetDescriptorByFileObject(EmuFileObject *object)
  298. +{
  299. + int i = object - m_files;
  300. + if (i >= 0 && i < MAX_EMULATED_FILES)
  301. + {
  302. + return 0x7000000 + i;
  303. + }
  304. +
  305. + return -1;
  306. +}
  307. +
  308. EmuFileObject* CEmuFileWrapper::GetFileObjectByStream(FILE* stream)
  309. {
  310. - if (isValidFilePtr(stream))
  311. + EmuFileObject *object = (EmuFileObject*) stream;
  312. + if (object >= &m_files[0] || object < &m_files[MAX_EMULATED_FILES])
  313. {
  314. - return GetFileObjectByDescriptor(FileDescriptor(*stream)->_file);
  315. + if (object->file_xbmc)
  316. + {
  317. + return object;
  318. + }
  319. }
  320. + return NULL;
  321. +}
  322. - return nullptr;
  323. +FILE* CEmuFileWrapper::GetStreamByFileObject(EmuFileObject *object)
  324. +{
  325. + return (FILE*) object;
  326. }
  327. XFILE::CFile* CEmuFileWrapper::GetFileXbmcByDescriptor(int fd)
  328. {
  329. auto object = GetFileObjectByDescriptor(fd);
  330. - if (object != nullptr && object->used)
  331. + if (object != nullptr)
  332. {
  333. return object->file_xbmc;
  334. }
  335. @@ -228,8 +206,9 @@ XFILE::CFile* CEmuFileWrapper::GetFileXbmcByStream(FILE* stream)
  336. {
  337. if (isValidFilePtr(stream))
  338. {
  339. - auto object = GetFileObjectByDescriptor(FileDescriptor(*stream)->_file);
  340. - if (object != nullptr && object->used)
  341. + EmuFileObject* object = GetFileObjectByStream(stream);
  342. + if (object != NULL)
  343. +
  344. {
  345. return object->file_xbmc;
  346. }
  347. @@ -239,32 +218,21 @@ XFILE::CFile* CEmuFileWrapper::GetFileXbmcByStream(FILE* stream)
  348. int CEmuFileWrapper::GetDescriptorByStream(FILE* stream)
  349. {
  350. - if (isValidFilePtr(stream))
  351. - {
  352. - int i = FileDescriptor(*stream)->_file - FILE_WRAPPER_OFFSET;
  353. - if (i >= 0 && i < MAX_EMULATED_FILES)
  354. - {
  355. - return i + FILE_WRAPPER_OFFSET;
  356. - }
  357. - }
  358. - return -1;
  359. + return GetDescriptorByFileObject(GetFileObjectByStream(stream));
  360. }
  361. FILE* CEmuFileWrapper::GetStreamByDescriptor(int fd)
  362. {
  363. - auto object = GetFileObjectByDescriptor(fd);
  364. - if (object != nullptr && object->used)
  365. - {
  366. - return &object->file_emu;
  367. - }
  368. - return nullptr;
  369. + return GetStreamByFileObject(GetFileObjectByDescriptor(fd));
  370. +}
  371. +
  372. +bool CEmuFileWrapper::DescriptorIsEmulatedFile(int fd)
  373. +{
  374. + return GetFileObjectByDescriptor(fd) != NULL;
  375. }
  376. bool CEmuFileWrapper::StreamIsEmulatedFile(FILE* stream)
  377. {
  378. - if (isValidFilePtr(stream))
  379. - {
  380. - return DescriptorIsEmulatedFile(FileDescriptor(*stream)->_file);
  381. - }
  382. - return false;
  383. + return GetFileObjectByStream(stream) != NULL;
  384. }
  385. +
  386. diff --git a/xbmc/cores/DllLoader/exports/util/EmuFileWrapper.h b/xbmc/cores/DllLoader/exports/util/EmuFileWrapper.h
  387. index 786fa85..311a5cf 100644
  388. --- a/xbmc/cores/DllLoader/exports/util/EmuFileWrapper.h
  389. +++ b/xbmc/cores/DllLoader/exports/util/EmuFileWrapper.h
  390. @@ -25,14 +25,14 @@
  391. #include "system.h"
  392. #include "threads/CriticalSection.h"
  393. -#if defined(TARGET_POSIX) && !defined(TARGET_DARWIN) && !defined(TARGET_FREEBSD) && !defined(TARGET_ANDROID) && !defined(__UCLIBC__)
  394. -#define _file _fileno
  395. -#elif defined(__UCLIBC__)
  396. -#define _file __filedes
  397. -#endif
  398. +//#if defined(TARGET_POSIX) && !defined(TARGET_DARWIN) && !defined(TARGET_FREEBSD) && !defined(TARGET_ANDROID) && !defined(__UCLIBC__)
  399. +//#define _file _fileno
  400. +//#elif defined(__UCLIBC__)
  401. +//#define _file __filedes
  402. +//#endif
  403. #define MAX_EMULATED_FILES 50
  404. -#define FILE_WRAPPER_OFFSET 0x00000200
  405. +//#define FILE_WRAPPER_OFFSET 0x00000200
  406. namespace XFILE
  407. {
  408. @@ -47,12 +47,9 @@ struct kodi_iobuf {
  409. typedef struct stEmuFileObject
  410. {
  411. - FILE file_emu;
  412. XFILE::CFile* file_xbmc;
  413. CCriticalSection *file_lock;
  414. int mode;
  415. - //Stick this last to avoid 3-7 bytes of padding
  416. - bool used;
  417. } EmuFileObject;
  418. class CEmuFileWrapper
  419. @@ -67,22 +64,22 @@ public:
  420. void CleanUp();
  421. EmuFileObject* RegisterFileObject(XFILE::CFile* pFile);
  422. + void UnRegisterFileObject(EmuFileObject*, bool free_file);
  423. void UnRegisterFileObjectByDescriptor(int fd);
  424. void UnRegisterFileObjectByStream(FILE* stream);
  425. void LockFileObjectByDescriptor(int fd);
  426. bool TryLockFileObjectByDescriptor(int fd);
  427. void UnlockFileObjectByDescriptor(int fd);
  428. EmuFileObject* GetFileObjectByDescriptor(int fd);
  429. + int GetDescriptorByFileObject(EmuFileObject*);
  430. EmuFileObject* GetFileObjectByStream(FILE* stream);
  431. + FILE* GetStreamByFileObject(EmuFileObject*);
  432. XFILE::CFile* GetFileXbmcByDescriptor(int fd);
  433. XFILE::CFile* GetFileXbmcByStream(FILE* stream);
  434. - static int GetDescriptorByStream(FILE* stream);
  435. + int GetDescriptorByStream(FILE* stream);
  436. FILE* GetStreamByDescriptor(int fd);
  437. - static constexpr bool DescriptorIsEmulatedFile(int fd)
  438. - {
  439. - return fd >= FILE_WRAPPER_OFFSET && fd < FILE_WRAPPER_OFFSET + MAX_EMULATED_FILES;
  440. - }
  441. - static bool StreamIsEmulatedFile(FILE* stream);
  442. + bool DescriptorIsEmulatedFile(int fd);
  443. + bool StreamIsEmulatedFile(FILE* stream);
  444. private:
  445. EmuFileObject m_files[MAX_EMULATED_FILES];
  446. CCriticalSection m_criticalSection;
  447. diff --git a/xbmc/cores/DllLoader/exports/wrapper.c b/xbmc/cores/DllLoader/exports/wrapper.c
  448. index e363662..07825f3 100644
  449. --- a/xbmc/cores/DllLoader/exports/wrapper.c
  450. +++ b/xbmc/cores/DllLoader/exports/wrapper.c
  451. @@ -39,13 +39,13 @@
  452. #endif
  453. #include <dlfcn.h>
  454. -#if defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID)
  455. +#if defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID) || !defined(__GLIBC__)
  456. typedef off_t __off_t;
  457. typedef int64_t off64_t;
  458. typedef off64_t __off64_t;
  459. typedef fpos_t fpos64_t;
  460. #define stat64 stat
  461. -#if defined(TARGET_DARWIN) || defined(TARGET_ANDROID)
  462. +#if defined(TARGET_DARWIN) || defined(TARGET_ANDROID) || !defined(__GLIBC__)
  463. #define _G_va_list va_list
  464. #endif
  465. #endif
  466. --
  467. 2.10.2