Skip to content

Commit

Permalink
- report correct macOS version with older SDKs
Browse files Browse the repository at this point in the history
When built against 10.15 SDK or earlier, macOS 11.0+ returns 10.16 for compatibility, and external process is needed to output the actual version for us
  • Loading branch information
alexey-lysiuk authored and coelckers committed Jul 25, 2021
1 parent b409dab commit f679e88
Showing 1 changed file with 66 additions and 3 deletions.
69 changes: 66 additions & 3 deletions src/common/platform/posix/cocoa/i_main.mm
Expand Up @@ -35,6 +35,7 @@
#include "s_soundinternal.h"

#include <sys/sysctl.h>
#include <sys/stat.h>

#include "c_console.h"
#include "c_cvars.h"
Expand Down Expand Up @@ -89,14 +90,76 @@ - (NSOperatingSystemVersion)operatingSystemVersion;

#endif // before 10.10

static bool ReadSystemVersionFromPlist(NSOperatingSystemVersion& version)
{
#if MAC_OS_X_VERSION_MAX_ALLOWED < 110000
// The version returned by macOS depends on the SDK which the software has been built against.
// When built against the 10.15 SDK or earlier, Big Sur returns 10.16 for compatibility with previous numbering.
// When built against the 11.0 SDK, it returns 11.0 for forward compatibility.
// https://eclecticlight.co/2020/08/13/macos-version-numbering-isnt-so-simple/

// It's impossible to load real SystemVersion.plist when linking with old SDK, i.e. when building for Intel CPU
// Any attempt to read this file is redirected to SystemVersionCompat.plist silently
// Workaround with the external process is needed in order to report correct macOS version

const char *const plistPath = "/System/Library/CoreServices/SystemVersion.plist";
struct stat dummy;

if (stat(plistPath, &dummy) != 0)
return false;

char commandLine[1024] = {};
snprintf(commandLine, sizeof commandLine, "defaults read %s ProductVersion", plistPath);

FILE *const versionFile = popen(commandLine, "r");

if (versionFile == nullptr)
return false;

NSOperatingSystemVersion plistVersion = {};
char versionString[256] = {};

if (fgets(versionString, sizeof versionString, versionFile))
{
plistVersion.majorVersion = atoi(versionString);

if (const char *minorVersionString = strstr(versionString, "."))
{
minorVersionString++;
plistVersion.minorVersion = atoi(minorVersionString);

if (const char *patchVersionString = strstr(minorVersionString, "."))
{
patchVersionString++;
plistVersion.patchVersion = atoi(minorVersionString);
}
}
}

fclose(versionFile);

if (plistVersion.majorVersion != 0)
{
version = plistVersion;
return true;
}
#endif // MAC_OS_X_VERSION_MAX_ALLOWED < 110000

return false;
}

void I_DetectOS()
{
NSOperatingSystemVersion version = {};
NSProcessInfo* const processInfo = [NSProcessInfo processInfo];

if ([processInfo respondsToSelector:@selector(operatingSystemVersion)])
if (!ReadSystemVersionFromPlist(version))
{
version = [processInfo operatingSystemVersion];
NSProcessInfo *const processInfo = [NSProcessInfo processInfo];

if ([processInfo respondsToSelector:@selector(operatingSystemVersion)])
{
version = [processInfo operatingSystemVersion];
}
}

const char* name = "Unknown version";
Expand Down

0 comments on commit f679e88

Please sign in to comment.