macOS os.getversion() improvements
* Use system property list to retrieve current accurate system version * Add description for latest versions
This commit is contained in:
parent
5fa6d359c1
commit
55099c4bd2
@ -108,6 +108,7 @@ int getversion(struct OsVersionInfo* info)
|
||||
|
||||
#elif defined(PLATFORM_MACOSX)
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <string.h>
|
||||
@ -115,76 +116,152 @@ int getversion(struct OsVersionInfo* info)
|
||||
|
||||
int getversion(struct OsVersionInfo* info)
|
||||
{
|
||||
const char * propertyListFilePath = "/System/Library/CoreServices/SystemVersion.plist";
|
||||
Boolean fallback = TRUE;
|
||||
|
||||
info->description = "Mac OS";
|
||||
info->majorversion = 10;
|
||||
|
||||
int mib[] = { CTL_KERN, KERN_OSRELEASE };
|
||||
size_t len;
|
||||
sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &len, NULL, 0);
|
||||
|
||||
char kernel_version[len];
|
||||
sysctl(mib, sizeof(mib) / sizeof(mib[0]), kernel_version, &len, NULL, 0);
|
||||
|
||||
int kern_major;
|
||||
int kern_minor;
|
||||
sscanf(kernel_version, "%d.%d.%*d", &kern_major, &kern_minor);
|
||||
switch (kern_major)
|
||||
if (access (propertyListFilePath, R_OK) == 0)
|
||||
{
|
||||
case 8:
|
||||
info->description = "Mac OS X Tiger";
|
||||
info->majorversion = 10;
|
||||
info->minorversion = 4;
|
||||
info->revision = kern_minor;
|
||||
CFPropertyListFormat format;
|
||||
CFErrorRef errorDescriptor = NULL;
|
||||
CFStringRef stringRef = NULL;
|
||||
CFURLRef urlRef = NULL;
|
||||
CFReadStreamRef streamRef = NULL;
|
||||
CFPropertyListRef propertyListRef = NULL;
|
||||
CFTypeID typeId = 0;
|
||||
Boolean result = FALSE;
|
||||
|
||||
stringRef = CFStringCreateWithCStringNoCopy(
|
||||
kCFAllocatorDefault,
|
||||
propertyListFilePath,
|
||||
kCFStringEncodingASCII,
|
||||
kCFAllocatorNull);
|
||||
if (stringRef == NULL)
|
||||
{
|
||||
goto getversion_macosx_cleanup;
|
||||
};
|
||||
|
||||
urlRef = CFURLCreateWithFileSystemPath(
|
||||
kCFAllocatorDefault,
|
||||
stringRef,
|
||||
kCFURLPOSIXPathStyle,
|
||||
false);
|
||||
if (urlRef == NULL)
|
||||
{
|
||||
goto getversion_macosx_cleanup;
|
||||
}
|
||||
|
||||
streamRef = CFReadStreamCreateWithFile(
|
||||
kCFAllocatorDefault,
|
||||
urlRef);
|
||||
if (streamRef == NULL)
|
||||
{
|
||||
goto getversion_macosx_cleanup;
|
||||
}
|
||||
|
||||
result = CFReadStreamOpen (streamRef);
|
||||
|
||||
if (result == FALSE)
|
||||
{
|
||||
goto getversion_macosx_cleanup;
|
||||
}
|
||||
|
||||
propertyListRef = CFPropertyListCreateWithStream(
|
||||
kCFAllocatorDefault,
|
||||
streamRef,
|
||||
0,
|
||||
kCFPropertyListImmutable,
|
||||
&format,
|
||||
&errorDescriptor);
|
||||
|
||||
CFReadStreamClose (streamRef);
|
||||
|
||||
if (!(propertyListRef && CFPropertyListIsValid(propertyListRef, format)) || errorDescriptor)
|
||||
{
|
||||
goto getversion_macosx_cleanup;
|
||||
}
|
||||
|
||||
typeId = CFGetTypeID(propertyListRef);
|
||||
if (typeId == CFDictionaryGetTypeID())
|
||||
{
|
||||
const CFDictionaryRef dictionaryRef = (const CFDictionaryRef)propertyListRef;
|
||||
char versionString[128];
|
||||
CFStringRef stringValueRef = NULL;
|
||||
if (CFDictionaryGetValueIfPresent(dictionaryRef, CFSTR("ProductVersion"), (const void **)(&stringValueRef)))
|
||||
{
|
||||
CFStringGetCString(stringValueRef, &versionString[0], (CFIndex)sizeof (versionString), kCFStringEncodingASCII);
|
||||
sscanf (versionString, "%d.%d.%d", &info->majorversion, &info->minorversion, &info->revision);
|
||||
|
||||
fallback = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
getversion_macosx_cleanup:
|
||||
|
||||
if (propertyListRef) CFRelease (propertyListRef);
|
||||
if (streamRef) CFRelease (streamRef);
|
||||
if (urlRef) CFRelease (urlRef);
|
||||
if (stringRef) CFRelease (stringRef);
|
||||
}
|
||||
|
||||
if (fallback == TRUE)
|
||||
{
|
||||
int mib[] = { CTL_KERN, KERN_OSRELEASE };
|
||||
size_t len;
|
||||
sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &len, NULL, 0);
|
||||
|
||||
char kernel_version[len];
|
||||
sysctl(mib, sizeof(mib) / sizeof(mib[0]), kernel_version, &len, NULL, 0);
|
||||
|
||||
int kern_major;
|
||||
int kern_minor;
|
||||
sscanf(kernel_version, "%d.%d.%*d", &kern_major, &kern_minor);
|
||||
|
||||
info->minorversion = kern_major - 4;
|
||||
info->revision = kern_minor;
|
||||
}
|
||||
|
||||
if (info->majorversion == 10)
|
||||
{
|
||||
switch (info->minorversion)
|
||||
{
|
||||
case 4:
|
||||
info->description = "Mac OS X Tiger";
|
||||
break;
|
||||
case 9:
|
||||
info->description = "Mac OS X Leopard";
|
||||
info->majorversion = 10;
|
||||
info->minorversion = 5;
|
||||
info->revision = kern_minor;
|
||||
case 5:
|
||||
info->description = "Mac OS X Leopard";
|
||||
break;
|
||||
case 10:
|
||||
info->description = "Mac OS X Snow Leopard";
|
||||
info->majorversion = 10;
|
||||
info->minorversion = 6;
|
||||
info->revision = kern_minor;
|
||||
case 6:
|
||||
info->description = "Mac OS X Snow Leopard";
|
||||
break;
|
||||
case 11:
|
||||
info->description = "OS X Lion";
|
||||
info->majorversion = 10;
|
||||
info->minorversion = 7;
|
||||
info->revision = kern_minor;
|
||||
case 7:
|
||||
info->description = "OS X Lion";
|
||||
break;
|
||||
case 12:
|
||||
info->description = "OS X Mountain Lion";
|
||||
info->majorversion = 10;
|
||||
info->minorversion = 8;
|
||||
info->revision = kern_minor;
|
||||
case 8:
|
||||
info->description = "OS X Mountain Lion";
|
||||
break;
|
||||
case 13:
|
||||
info->description = "OS X Mavericks";
|
||||
info->majorversion = 10;
|
||||
info->minorversion = 9;
|
||||
info->revision = kern_minor;
|
||||
case 9:
|
||||
info->description = "OS X Mavericks";
|
||||
case 10:
|
||||
info->description = "OS X Yosemite";
|
||||
case 11:
|
||||
info->description = "OS X El Capitan";
|
||||
break;
|
||||
case 14:
|
||||
info->description = "OS X Yosemite";
|
||||
info->majorversion = 10;
|
||||
info->minorversion = 10;
|
||||
info->revision = kern_minor;
|
||||
case 12:
|
||||
info->description = "macOS Sierra";
|
||||
break;
|
||||
case 15:
|
||||
info->description = "OS X El Capitan";
|
||||
info->majorversion = 10;
|
||||
info->minorversion = 11;
|
||||
info->revision = kern_minor;
|
||||
case 13:
|
||||
info->description = "macOS High Sierra";
|
||||
break;
|
||||
case 16:
|
||||
info->description = "macOS Sierra";
|
||||
info->majorversion = 10;
|
||||
info->minorversion = 12;
|
||||
info->revision = kern_minor;
|
||||
case 14:
|
||||
info->description = "macOS Mojave";
|
||||
break;
|
||||
default:
|
||||
case 15:
|
||||
info->description = "macOS Catalina";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
Reference in New Issue
Block a user