[dart:io] Adds Platform.operatingSystemVersion

fixes #30018

R=rmacnak@google.com

Review-Url: https://codereview.chromium.org/3006873002 .
This commit is contained in:
Zachary Anderson
2017-09-01 22:08:45 -07:00
parent a914c24b43
commit e2bce948ed
15 changed files with 249 additions and 13 deletions
+2
View File
@@ -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");
+1
View File
@@ -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) \
+9
View File
@@ -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()));
}
+5
View File
@@ -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() {
+26 -3
View File
@@ -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";
}
+23
View File
@@ -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";
}
+26 -3
View File
@@ -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";
}
+28 -5
View File
@@ -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";
}
+2
View File
@@ -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";
+83
View File
@@ -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");
+6
View File
@@ -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.
*/
+14 -2
View File
@@ -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);
}