[dart:io] Adds Platform.operatingSystemVersion
fixes #30018 R=rmacnak@google.com Review-Url: https://codereview.chromium.org/3006873002 .
This commit is contained in:
@@ -26,6 +26,8 @@
|
||||
will be thrown. Note: if the duration specified in 'timeout' is greater than
|
||||
the system level timeout duration, a timeout may occur sooner than specified
|
||||
in 'timeout'.
|
||||
* Added `Platform.operatingSystemVersion` that gives a platform-specific
|
||||
String describing the version of the operating system.
|
||||
|
||||
* `dart:core`
|
||||
* The `Uri` class now correctly handles paths while running on Node.js on
|
||||
|
||||
@@ -233,6 +233,11 @@ class _Platform {
|
||||
throw new UnsupportedError("Platform._operatingSystem");
|
||||
}
|
||||
|
||||
@patch
|
||||
static _operatingSystemVersion() {
|
||||
throw new UnsupportedError("Platform._operatingSystemVersion");
|
||||
}
|
||||
|
||||
@patch
|
||||
static _localHostname() {
|
||||
throw new UnsupportedError("Platform._localHostname");
|
||||
|
||||
@@ -87,6 +87,7 @@ namespace bin {
|
||||
V(NetworkInterface_ListSupported, 0) \
|
||||
V(Platform_NumberOfProcessors, 0) \
|
||||
V(Platform_OperatingSystem, 0) \
|
||||
V(Platform_OperatingSystemVersion, 0) \
|
||||
V(Platform_PathSeparator, 0) \
|
||||
V(Platform_LocalHostname, 0) \
|
||||
V(Platform_ExecutableName, 0) \
|
||||
|
||||
@@ -19,6 +19,15 @@ void FUNCTION_NAME(Platform_OperatingSystem)(Dart_NativeArguments args) {
|
||||
Dart_SetReturnValue(args, DartUtils::NewString(Platform::OperatingSystem()));
|
||||
}
|
||||
|
||||
void FUNCTION_NAME(Platform_OperatingSystemVersion)(Dart_NativeArguments args) {
|
||||
const char* version = Platform::OperatingSystemVersion();
|
||||
if (version == NULL) {
|
||||
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
|
||||
} else {
|
||||
Dart_SetReturnValue(args, DartUtils::NewString(version));
|
||||
}
|
||||
}
|
||||
|
||||
void FUNCTION_NAME(Platform_PathSeparator)(Dart_NativeArguments args) {
|
||||
Dart_SetReturnValue(args, DartUtils::NewString(File::PathSeparator()));
|
||||
}
|
||||
|
||||
@@ -24,6 +24,11 @@ class Platform {
|
||||
// deallocated by the caller.
|
||||
static const char* OperatingSystem();
|
||||
|
||||
// Returns a string representing the version of the operating system. The
|
||||
// format of the string is determined by the platform. The returned string
|
||||
// should not be deallocated by the caller.
|
||||
static const char* OperatingSystemVersion();
|
||||
|
||||
// Returns the architecture name of the processor the VM is running on
|
||||
// (ia32, x64, arm, or arm64).
|
||||
static const char* HostArchitecture() {
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
|
||||
#include "bin/platform.h"
|
||||
|
||||
#include <signal.h> // NOLINT
|
||||
#include <string.h> // NOLINT
|
||||
#include <unistd.h> // NOLINT
|
||||
#include <signal.h> // NOLINT
|
||||
#include <string.h> // NOLINT
|
||||
#include <sys/utsname.h> // NOLINT
|
||||
#include <unistd.h> // NOLINT
|
||||
|
||||
#include "bin/fdutils.h"
|
||||
#include "bin/file.h"
|
||||
@@ -73,6 +74,28 @@ const char* Platform::OperatingSystem() {
|
||||
return "android";
|
||||
}
|
||||
|
||||
const char* Platform::OperatingSystemVersion() {
|
||||
struct utsname info;
|
||||
int ret = uname(&info);
|
||||
if (ret != 0) {
|
||||
return NULL;
|
||||
}
|
||||
const char* kFormat = "%s %s %s";
|
||||
int len =
|
||||
snprintf(NULL, 0, kFormat, info.sysname, info.release, info.version);
|
||||
if (len <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
char* result = DartUtils::ScopedCString(len + 1);
|
||||
ASSERT(result != NULL);
|
||||
len = snprintf(result, len + 1, kFormat, info.sysname, info.release,
|
||||
info.version);
|
||||
if (len <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* Platform::LibraryPrefix() {
|
||||
return "lib";
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <magenta/status.h>
|
||||
#include <magenta/syscalls.h>
|
||||
#include <string.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "bin/dartutils.h"
|
||||
@@ -37,6 +38,28 @@ const char* Platform::OperatingSystem() {
|
||||
return "fuchsia";
|
||||
}
|
||||
|
||||
const char* Platform::OperatingSystemVersion() {
|
||||
struct utsname info;
|
||||
int ret = uname(&info);
|
||||
if (ret != 0) {
|
||||
return NULL;
|
||||
}
|
||||
const char* kFormat = "%s %s %s";
|
||||
int len =
|
||||
snprintf(NULL, 0, kFormat, info.sysname, info.release, info.version);
|
||||
if (len <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
char* result = DartUtils::ScopedCString(len + 1);
|
||||
ASSERT(result != NULL);
|
||||
len = snprintf(result, len + 1, kFormat, info.sysname, info.release,
|
||||
info.version);
|
||||
if (len <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* Platform::LibraryPrefix() {
|
||||
return "lib";
|
||||
}
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
|
||||
#include "bin/platform.h"
|
||||
|
||||
#include <signal.h> // NOLINT
|
||||
#include <string.h> // NOLINT
|
||||
#include <unistd.h> // NOLINT
|
||||
#include <signal.h> // NOLINT
|
||||
#include <string.h> // NOLINT
|
||||
#include <sys/utsname.h> // NOLINT
|
||||
#include <unistd.h> // NOLINT
|
||||
|
||||
#include "bin/fdutils.h"
|
||||
#include "bin/file.h"
|
||||
@@ -72,6 +73,28 @@ const char* Platform::OperatingSystem() {
|
||||
return "linux";
|
||||
}
|
||||
|
||||
const char* Platform::OperatingSystemVersion() {
|
||||
struct utsname info;
|
||||
int ret = uname(&info);
|
||||
if (ret != 0) {
|
||||
return NULL;
|
||||
}
|
||||
const char* kFormat = "%s %s %s";
|
||||
int len =
|
||||
snprintf(NULL, 0, kFormat, info.sysname, info.release, info.version);
|
||||
if (len <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
char* result = DartUtils::ScopedCString(len + 1);
|
||||
ASSERT(result != NULL);
|
||||
len = snprintf(result, len + 1, kFormat, info.sysname, info.release,
|
||||
info.version);
|
||||
if (len <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* Platform::LibraryPrefix() {
|
||||
return "lib";
|
||||
}
|
||||
|
||||
@@ -13,11 +13,12 @@
|
||||
#include <crt_externs.h> // NOLINT
|
||||
#endif // !HOST_OS_IOS
|
||||
#include <mach-o/dyld.h>
|
||||
#include <signal.h> // NOLINT
|
||||
#include <string.h> // NOLINT
|
||||
#include <sys/sysctl.h> // NOLINT
|
||||
#include <sys/types.h> // NOLINT
|
||||
#include <unistd.h> // NOLINT
|
||||
#include <signal.h> // NOLINT
|
||||
#include <string.h> // NOLINT
|
||||
#include <sys/sysctl.h> // NOLINT
|
||||
#include <sys/types.h> // NOLINT
|
||||
#include <sys/utsname.h> // NOLINT
|
||||
#include <unistd.h> // NOLINT
|
||||
|
||||
#include "bin/fdutils.h"
|
||||
#include "bin/file.h"
|
||||
@@ -90,6 +91,28 @@ const char* Platform::OperatingSystem() {
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* Platform::OperatingSystemVersion() {
|
||||
struct utsname info;
|
||||
int ret = uname(&info);
|
||||
if (ret != 0) {
|
||||
return NULL;
|
||||
}
|
||||
const char* kFormat = "%s %s %s";
|
||||
int len =
|
||||
snprintf(NULL, 0, kFormat, info.sysname, info.release, info.version);
|
||||
if (len <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
char* result = DartUtils::ScopedCString(len + 1);
|
||||
ASSERT(result != NULL);
|
||||
len = snprintf(result, len + 1, kFormat, info.sysname, info.release,
|
||||
info.version);
|
||||
if (len <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* Platform::LibraryPrefix() {
|
||||
return "lib";
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ class _Platform {
|
||||
@patch
|
||||
static String _operatingSystem() native "Platform_OperatingSystem";
|
||||
@patch
|
||||
static _operatingSystemVersion() native "Platform_OperatingSystemVersion";
|
||||
@patch
|
||||
static _localHostname() native "Platform_LocalHostname";
|
||||
@patch
|
||||
static _executable() native "Platform_ExecutableName";
|
||||
|
||||
@@ -213,6 +213,89 @@ const char* Platform::OperatingSystem() {
|
||||
return "windows";
|
||||
}
|
||||
|
||||
// We pull the version number, and other version information out of the
|
||||
// registry because GetVersionEx() and friends lie about the OS version after
|
||||
// Windows 8.1. See:
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724451(v=vs.85).aspx
|
||||
static const wchar_t* kCurrentVersion =
|
||||
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
|
||||
|
||||
static bool GetCurrentVersionDWord(const wchar_t* field, DWORD* value) {
|
||||
DWORD value_size = sizeof(*value);
|
||||
LONG err = RegGetValue(HKEY_LOCAL_MACHINE, kCurrentVersion, field,
|
||||
RRF_RT_REG_DWORD, NULL, value, &value_size);
|
||||
return err == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static bool GetCurrentVersionString(const wchar_t* field, const char** value) {
|
||||
wchar_t wversion[256];
|
||||
DWORD wversion_size = sizeof(wversion);
|
||||
LONG err = RegGetValue(HKEY_LOCAL_MACHINE, kCurrentVersion, field,
|
||||
RRF_RT_REG_SZ, NULL, wversion, &wversion_size);
|
||||
if (err != ERROR_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
*value = StringUtilsWin::WideToUtf8(wversion);
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char* VersionNumber() {
|
||||
// Try to get CurrentMajorVersionNumber. If that fails, fall back on
|
||||
// CurrentVersion. If it succeeds also get CurrentMinorVersionNumber.
|
||||
DWORD major;
|
||||
if (!GetCurrentVersionDWord(L"CurrentMajorVersionNumber", &major)) {
|
||||
const char* version;
|
||||
if (!GetCurrentVersionString(L"CurrentVersion", &version)) {
|
||||
return NULL;
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
DWORD minor;
|
||||
if (!GetCurrentVersionDWord(L"CurrentMinorVersionNumber", &minor)) {
|
||||
return NULL;
|
||||
}
|
||||
const char* kFormat = "%d.%d";
|
||||
int len = snprintf(NULL, 0, kFormat, major, minor);
|
||||
if (len < 0) {
|
||||
return NULL;
|
||||
}
|
||||
char* result = DartUtils::ScopedCString(len + 1);
|
||||
ASSERT(result != NULL);
|
||||
len = snprintf(result, len + 1, kFormat, major, minor);
|
||||
if (len < 0) {
|
||||
return NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* Platform::OperatingSystemVersion() {
|
||||
// Get the product name, e.g. "Windows 10 Home".
|
||||
const char* name;
|
||||
if (!GetCurrentVersionString(L"ProductName", &name)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get the version number, e.g. "10.0".
|
||||
const char* version_number = VersionNumber();
|
||||
if (version_number == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get the build number.
|
||||
const char* build;
|
||||
if (!GetCurrentVersionString(L"CurrentBuild", &build)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Put it all together.
|
||||
const char* kFormat = "\"%s\" %s (Build %s)";
|
||||
int len = snprintf(NULL, 0, kFormat, name, version_number, build);
|
||||
char* result = DartUtils::ScopedCString(len + 1);
|
||||
len = snprintf(result, len + 1, kFormat, name, version_number, build);
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* Platform::LibraryPrefix() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -233,6 +233,11 @@ class _Platform {
|
||||
throw new UnsupportedError("Platform._operatingSystem");
|
||||
}
|
||||
|
||||
@patch
|
||||
static _operatingSystemVersion() {
|
||||
throw new UnsupportedError("Platform._operatingSystemVersion");
|
||||
}
|
||||
|
||||
@patch
|
||||
static _localHostname() {
|
||||
throw new UnsupportedError("Platform._localHostname");
|
||||
|
||||
@@ -69,6 +69,7 @@ class Platform {
|
||||
static final _numberOfProcessors = _Platform.numberOfProcessors;
|
||||
static final _pathSeparator = _Platform.pathSeparator;
|
||||
static final _operatingSystem = _Platform.operatingSystem;
|
||||
static final _operatingSystemVersion = _Platform.operatingSystemVersion;
|
||||
static final _localHostname = _Platform.localHostname;
|
||||
static final _version = _Platform.version;
|
||||
static final _localeName = _Platform.localeName;
|
||||
@@ -94,6 +95,11 @@ class Platform {
|
||||
*/
|
||||
static String get operatingSystem => _operatingSystem;
|
||||
|
||||
/**
|
||||
* A string representing the version of the operating system or platform.
|
||||
*/
|
||||
static String get operatingSystemVersion => _operatingSystemVersion;
|
||||
|
||||
/**
|
||||
* The local hostname for the system.
|
||||
*/
|
||||
|
||||
@@ -8,6 +8,7 @@ class _Platform {
|
||||
external static int _numberOfProcessors();
|
||||
external static String _pathSeparator();
|
||||
external static String _operatingSystem();
|
||||
external static _operatingSystemVersion();
|
||||
external static _localHostname();
|
||||
external static _executable();
|
||||
external static _resolvedExecutable();
|
||||
@@ -61,13 +62,24 @@ class _Platform {
|
||||
static String get operatingSystem => _operatingSystem();
|
||||
static Uri get script => _script();
|
||||
|
||||
static String _cachedOSVersion;
|
||||
static String get operatingSystemVersion {
|
||||
if (_cachedOSVersion == null) {
|
||||
var result = _operatingSystemVersion();
|
||||
if (result is OSError) {
|
||||
throw result;
|
||||
}
|
||||
_cachedOSVersion = result;
|
||||
}
|
||||
return _cachedOSVersion;
|
||||
}
|
||||
|
||||
static String get localHostname {
|
||||
var result = _localHostname();
|
||||
if (result is OSError) {
|
||||
throw result;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static List<String> get executableArguments => _executableArguments();
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import "dart:io";
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
main() {
|
||||
var version = Platform.operatingSystemVersion;
|
||||
Expect.isNotNull(version);
|
||||
Expect.isTrue(version is String);
|
||||
print(Platform.operatingSystemVersion);
|
||||
}
|
||||
Reference in New Issue
Block a user