| 824 | |
| 825 | |
| 826 | std::string getOperatingSystemInfo() { |
| 827 | #if defined ARCH_LIN |
| 828 | struct utsname u; |
| 829 | uname(&u); |
| 830 | return string::f("%s %s %s %s", u.sysname, u.release, u.version, u.machine); |
| 831 | #elif defined ARCH_MAC |
| 832 | // From https://opensource.apple.com/source/cctools/cctools-973.0.1/libstuff/macosx_deployment_target.c.auto.html |
| 833 | char osversion[32]; |
| 834 | size_t osversion_len = sizeof(osversion) - 1; |
| 835 | |
| 836 | // Available in Mac >=10.13 |
| 837 | if (sysctlbyname("kern.osproductversion", osversion, &osversion_len, NULL, 0) == 0) |
| 838 | return string::f("Mac %s", osversion); |
| 839 | |
| 840 | // Fallback: Get Darwin version and convert to Mac version |
| 841 | if (sysctlbyname("kern.osrelease", osversion, &osversion_len, NULL, 0) != 0) |
| 842 | return "Mac"; |
| 843 | |
| 844 | int major = 0; |
| 845 | int minor = 0; |
| 846 | if (sscanf(osversion, "%d.%d", &major, &minor) != 2) |
| 847 | return string::f("Mac Darwin %s", osversion); |
| 848 | |
| 849 | if (5 <= major && major <= 19) { |
| 850 | // Darwin 5 -> Mac 10.1, through Mac 10.15 |
| 851 | major -= 4; |
| 852 | return string::f("Mac 10.%d.%d", major, minor); |
| 853 | } |
| 854 | else { |
| 855 | return string::f("Mac Darwin %s", osversion); |
| 856 | } |
| 857 | #elif defined ARCH_WIN |
| 858 | OSVERSIONINFOW info; |
| 859 | ZeroMemory(&info, sizeof(info)); |
| 860 | info.dwOSVersionInfoSize = sizeof(info); |
| 861 | GetVersionExW(&info); |
| 862 | // See https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_osversioninfoa for a list of Windows version numbers. |
| 863 | return string::f("Windows %lu.%lu", info.dwMajorVersion, info.dwMinorVersion); |
| 864 | #endif |
| 865 | } |
| 866 | |
| 867 | |
| 868 | void openBrowser(const std::string& url) { |