33
33
#endif
34
34
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
35
35
#include <tzfile.h>
36
+ #define MACOS_TZDIR1 "/usr/share/zoneinfo/" // 10.12 and earlier
37
+ #define MACOS_TZDIR2 "/var/db/timezone/zoneinfo/" // 10.13 onwards
38
+
36
39
#elif DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
37
40
#ifndef TZDIR
38
- #define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */
41
+ #define TZDIR "/usr/share/zoneinfo/ " /* Time zone object file directory */
39
42
#endif /* !defined TZDIR */
40
43
41
44
#ifndef TZDEFAULT
@@ -56,16 +59,9 @@ struct tzhead {
56
59
57
60
#include <time.h>
58
61
59
- #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
60
- #define TZZONELINK TZDEFAULT
61
- #define TZZONEINFO TZDIR "/"
62
- #elif DEPLOYMENT_TARGET_WINDOWS
63
62
static CFStringRef __tzZoneInfo = NULL ;
64
63
static char * __tzDir = NULL ;
65
64
static void __InitTZStrings (void );
66
- #else
67
- #error Unknown or unspecified DEPLOYMENT_TARGET
68
- #endif
69
65
70
66
CONST_STRING_DECL (kCFTimeZoneSystemTimeZoneDidChangeNotification , "kCFTimeZoneSystemTimeZoneDidChangeNotification" )
71
67
@@ -147,13 +143,9 @@ static CFMutableArrayRef __CFCopyWindowsTimeZoneList() {
147
143
#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
148
144
static CFMutableArrayRef __CFCopyRecursiveDirectoryList () {
149
145
CFMutableArrayRef result = CFArrayCreateMutable (kCFAllocatorSystemDefault , 0 , & kCFTypeArrayCallBacks );
150
- #if DEPLOYMENT_TARGET_WINDOWS
151
146
if (!__tzDir ) __InitTZStrings ();
152
147
if (!__tzDir ) return result ;
153
148
int fd = open (__tzDir , O_RDONLY );
154
- #else
155
- int fd = open (TZDIR "/zone.tab" , O_RDONLY );
156
- #endif
157
149
158
150
for (; 0 <= fd ;) {
159
151
uint8_t buffer [4096 ];
@@ -686,7 +678,7 @@ CFTimeZoneRef CFTimeZoneCreateWithWindowsName(CFAllocatorRef allocator, CFString
686
678
}
687
679
688
680
extern CFStringRef _CFGetWindowsAppleSystemLibraryDirectory (void );
689
- void __InitTZStrings (void ) {
681
+ static void __InitTZStrings (void ) {
690
682
static CFLock_t __CFTZDirLock = CFLockInit ;
691
683
__CFLock (& __CFTZDirLock );
692
684
if (!__tzZoneInfo ) {
@@ -704,6 +696,50 @@ void __InitTZStrings(void) {
704
696
}
705
697
__CFUnlock (& __CFTZDirLock );
706
698
}
699
+
700
+ #elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
701
+ static void __InitTZStrings (void ) {
702
+ static dispatch_once_t initOnce = 0 ;
703
+
704
+ dispatch_once (& initOnce , ^{
705
+ unsigned int major = 0 , minor = 0 , patch = 0 ;
706
+
707
+ CFDictionaryRef dict = _CFCopySystemVersionDictionary ();
708
+ if (dict ) {
709
+ CFStringRef version = CFDictionaryGetValue (dict , _kCFSystemVersionProductVersionKey );
710
+ if (version ) {
711
+ const char * cStr = CFStringGetCStringPtr (version , kCFStringEncodingASCII );
712
+ if (cStr ) {
713
+ if (sscanf (cStr , "%u.%u.%u" , & major , & minor , & patch ) != 3 ) {
714
+ major = 0 ;
715
+ minor = 0 ;
716
+ patch = 0 ;
717
+ }
718
+ }
719
+ }
720
+ CFRelease (dict );
721
+ }
722
+
723
+ // Timezone files moved in High Sierra(10.13)
724
+ if (major == 10 && minor < 13 ) {
725
+ // older versions
726
+ __tzZoneInfo = CFSTR (MACOS_TZDIR1 );
727
+ __tzDir = MACOS_TZDIR1 "zone.tab" ;
728
+ } else {
729
+ __tzZoneInfo = CFSTR (MACOS_TZDIR2 );
730
+ __tzDir = MACOS_TZDIR2 "zone.tab" ;
731
+ }
732
+ });
733
+ }
734
+
735
+ #elif DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
736
+ static void __InitTZStrings (void ) {
737
+ __tzZoneInfo = CFSTR (TZDIR );
738
+ __tzDir = TZDIR "zone.tab" ;
739
+ }
740
+
741
+ #else
742
+ #error Unknown or unspecified DEPLOYMENT_TARGET
707
743
#endif
708
744
709
745
static CFTimeZoneRef __CFTimeZoneCreateSystem (void ) {
@@ -748,11 +784,16 @@ static CFTimeZoneRef __CFTimeZoneCreateSystem(void) {
748
784
CFRelease (name );
749
785
if (result ) return result ;
750
786
}
751
- ret = readlink (TZZONELINK , linkbuf , sizeof (linkbuf ));
752
- if (0 < ret ) {
787
+
788
+ if (!__tzZoneInfo ) __InitTZStrings ();
789
+ ret = readlink (TZDEFAULT , linkbuf , sizeof (linkbuf ));
790
+ if (__tzZoneInfo && (0 < ret )) {
753
791
linkbuf [ret ] = '\0' ;
754
- if (strncmp (linkbuf , TZZONEINFO , sizeof (TZZONEINFO ) - 1 ) == 0 ) {
755
- name = CFStringCreateWithBytes (kCFAllocatorSystemDefault , (uint8_t * )linkbuf + sizeof (TZZONEINFO ) - 1 , strlen (linkbuf ) - sizeof (TZZONEINFO ) + 1 , kCFStringEncodingUTF8 , false);
792
+ const char * tzZoneInfo = CFStringGetCStringPtr (__tzZoneInfo , kCFStringEncodingASCII );
793
+ size_t zoneInfoDirLen = CFStringGetLength (__tzZoneInfo );
794
+ if (strncmp (linkbuf , tzZoneInfo , zoneInfoDirLen ) == 0 ) {
795
+ name = CFStringCreateWithBytes (kCFAllocatorSystemDefault , (uint8_t * )linkbuf + zoneInfoDirLen ,
796
+ strlen (linkbuf ) - zoneInfoDirLen + 2 , kCFStringEncodingUTF8 , false);
756
797
} else {
757
798
name = CFStringCreateWithBytes (kCFAllocatorSystemDefault , (uint8_t * )linkbuf , strlen (linkbuf ), kCFStringEncodingUTF8 , false);
758
799
}
@@ -1133,12 +1174,12 @@ Boolean _CFTimeZoneInit(CFTimeZoneRef timeZone, CFStringRef name, CFDataRef data
1133
1174
CFIndex length ;
1134
1175
Boolean result = false;
1135
1176
1136
- #if DEPLOYMENT_TARGET_WINDOWS
1137
1177
if (!__tzZoneInfo ) __InitTZStrings ();
1138
1178
if (!__tzZoneInfo ) return NULL ;
1179
+ #if DEPLOYMENT_TARGET_WINDOWS
1139
1180
baseURL = CFURLCreateWithFileSystemPath (kCFAllocatorSystemDefault , __tzZoneInfo , kCFURLWindowsPathStyle , true);
1140
1181
#else
1141
- baseURL = CFURLCreateWithFileSystemPath (kCFAllocatorSystemDefault , CFSTR ( TZZONEINFO ) , kCFURLPOSIXPathStyle , true);
1182
+ baseURL = CFURLCreateWithFileSystemPath (kCFAllocatorSystemDefault , __tzZoneInfo , kCFURLPOSIXPathStyle , true);
1142
1183
#endif
1143
1184
if (tryAbbrev ) {
1144
1185
CFDictionaryRef abbrevs = CFTimeZoneCopyAbbreviationDictionary ();
@@ -1159,15 +1200,9 @@ Boolean _CFTimeZoneInit(CFTimeZoneRef timeZone, CFStringRef name, CFDataRef data
1159
1200
CFStringRef mapping = CFDictionaryGetValue (dict , name );
1160
1201
if (mapping ) {
1161
1202
name = mapping ;
1162
- #if DEPLOYMENT_TARGET_WINDOWS
1163
1203
} else if (CFStringHasPrefix (name , __tzZoneInfo )) {
1164
1204
CFMutableStringRef unprefixed = CFStringCreateMutableCopy (kCFAllocatorSystemDefault , CFStringGetLength (name ), name );
1165
1205
CFStringDelete (unprefixed , CFRangeMake (0 , CFStringGetLength (__tzZoneInfo )));
1166
- #else
1167
- } else if (CFStringHasPrefix (name , CFSTR (TZZONEINFO ))) {
1168
- CFMutableStringRef unprefixed = CFStringCreateMutableCopy (kCFAllocatorSystemDefault , CFStringGetLength (name ), name );
1169
- CFStringDelete (unprefixed , CFRangeMake (0 , sizeof (TZZONEINFO )));
1170
- #endif
1171
1206
mapping = CFDictionaryGetValue (dict , unprefixed );
1172
1207
if (mapping ) {
1173
1208
name = mapping ;
@@ -1340,12 +1375,12 @@ CFTimeZoneRef CFTimeZoneCreateWithName(CFAllocatorRef allocator, CFStringRef nam
1340
1375
void * bytes ;
1341
1376
CFIndex length ;
1342
1377
1343
- #if DEPLOYMENT_TARGET_WINDOWS
1344
1378
if (!__tzZoneInfo ) __InitTZStrings ();
1345
1379
if (!__tzZoneInfo ) return NULL ;
1380
+ #if DEPLOYMENT_TARGET_WINDOWS
1346
1381
baseURL = CFURLCreateWithFileSystemPath (kCFAllocatorSystemDefault , __tzZoneInfo , kCFURLWindowsPathStyle , true);
1347
1382
#else
1348
- baseURL = CFURLCreateWithFileSystemPath (kCFAllocatorSystemDefault , CFSTR ( TZZONEINFO ) , kCFURLPOSIXPathStyle , true);
1383
+ baseURL = CFURLCreateWithFileSystemPath (kCFAllocatorSystemDefault , __tzZoneInfo , kCFURLPOSIXPathStyle , true);
1349
1384
#endif
1350
1385
if (tryAbbrev ) {
1351
1386
CFDictionaryRef abbrevs = CFTimeZoneCopyAbbreviationDictionary ();
@@ -1366,15 +1401,9 @@ CFTimeZoneRef CFTimeZoneCreateWithName(CFAllocatorRef allocator, CFStringRef nam
1366
1401
CFStringRef mapping = CFDictionaryGetValue (dict , name );
1367
1402
if (mapping ) {
1368
1403
name = mapping ;
1369
- #if DEPLOYMENT_TARGET_WINDOWS
1370
1404
} else if (CFStringHasPrefix (name , __tzZoneInfo )) {
1371
1405
CFMutableStringRef unprefixed = CFStringCreateMutableCopy (kCFAllocatorSystemDefault , CFStringGetLength (name ), name );
1372
1406
CFStringDelete (unprefixed , CFRangeMake (0 , CFStringGetLength (__tzZoneInfo )));
1373
- #else
1374
- } else if (CFStringHasPrefix (name , CFSTR (TZZONEINFO ))) {
1375
- CFMutableStringRef unprefixed = CFStringCreateMutableCopy (kCFAllocatorSystemDefault , CFStringGetLength (name ), name );
1376
- CFStringDelete (unprefixed , CFRangeMake (0 , sizeof (TZZONEINFO )));
1377
- #endif
1378
1407
mapping = CFDictionaryGetValue (dict , unprefixed );
1379
1408
if (mapping ) {
1380
1409
name = mapping ;
@@ -1549,6 +1578,4 @@ static CFDictionaryRef __CFTimeZoneCopyCompatibilityDictionary(void) {
1549
1578
return dict ;
1550
1579
}
1551
1580
1552
- #undef TZZONEINFO
1553
- #undef TZZONELINK
1554
1581
0 commit comments