[ VM ] Fixed issue where error code was being clobbered by call to Dart_TypedDataReleaseData on Windows, resulting in OSError returning a 0 error instead of the true error code.
Bug: 2
Change-Id: I33e9319f57de73d9435936ddf853968834fb5a16
Reviewed-on: https://dart-review.googlesource.com/56461
Commit-Queue: Ben Konyi <bkonyi@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
diff --git a/runtime/bin/directory.cc b/runtime/bin/directory.cc
index 215cba3..4f89b2d 100644
--- a/runtime/bin/directory.cc
+++ b/runtime/bin/directory.cc
@@ -12,6 +12,7 @@
#include "bin/log.h"
#include "bin/namespace.h"
#include "bin/typed_data_utils.h"
+#include "bin/utils.h"
#include "include/dart_api.h"
#include "platform/assert.h"
@@ -33,6 +34,7 @@
void FUNCTION_NAME(Directory_SetCurrent)(Dart_NativeArguments args) {
Namespace* namespc = Namespace::GetNamespace(args, 0);
Dart_Handle path = Dart_GetNativeArgument(args, 1);
+ OSError os_error;
ASSERT(!Dart_IsError(path));
bool result;
{
@@ -40,11 +42,15 @@
ASSERT(data.type() == Dart_TypedData_kUint8);
const char* name = data.GetCString();
result = Directory::SetCurrent(namespc, name);
+ if (!result) {
+ // Errors must be caught before TypedDataScope data is destroyed.
+ os_error.Reload();
+ }
}
if (result) {
Dart_SetBooleanReturnValue(args, true);
} else {
- Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+ Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
}
}
@@ -53,36 +59,47 @@
static const int kDoesNotExist = 0;
Namespace* namespc = Namespace::GetNamespace(args, 0);
Dart_Handle path = Dart_GetNativeArgument(args, 1);
+ OSError os_error;
Directory::ExistsResult result;
{
TypedDataScope data(path);
ASSERT(data.type() == Dart_TypedData_kUint8);
const char* name = data.GetCString();
result = Directory::Exists(namespc, name);
+ if ((result != Directory::DOES_NOT_EXIST) ||
+ (result != Directory::EXISTS)) {
+ // Errors must be caught before TypedDataScope data is destroyed.
+ os_error.Reload();
+ }
}
if (result == Directory::EXISTS) {
Dart_SetIntegerReturnValue(args, kExists);
} else if (result == Directory::DOES_NOT_EXIST) {
Dart_SetIntegerReturnValue(args, kDoesNotExist);
} else {
- Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+ Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
}
}
void FUNCTION_NAME(Directory_Create)(Dart_NativeArguments args) {
Namespace* namespc = Namespace::GetNamespace(args, 0);
Dart_Handle path = Dart_GetNativeArgument(args, 1);
+ OSError os_error;
bool result;
{
TypedDataScope data(path);
ASSERT(data.type() == Dart_TypedData_kUint8);
const char* name = data.GetCString();
result = Directory::Create(namespc, name);
+ if (!result) {
+ // Errors must be caught before TypedDataScope data is destroyed.
+ os_error.Reload();
+ }
}
if (result) {
Dart_SetBooleanReturnValue(args, true);
} else {
- Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+ Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
}
}
@@ -95,23 +112,29 @@
void FUNCTION_NAME(Directory_CreateTemp)(Dart_NativeArguments args) {
Namespace* namespc = Namespace::GetNamespace(args, 0);
Dart_Handle path = Dart_GetNativeArgument(args, 1);
+ OSError os_error;
const char* result = NULL;
{
TypedDataScope data(path);
ASSERT(data.type() == Dart_TypedData_kUint8);
const char* name = data.GetCString();
result = Directory::CreateTemp(namespc, name);
+ if (result == NULL) {
+ // Errors must be caught before TypedDataScope data is destroyed.
+ os_error.Reload();
+ }
}
if (result != NULL) {
Dart_SetReturnValue(args, DartUtils::NewString(result));
} else {
- Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+ Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
}
}
void FUNCTION_NAME(Directory_Delete)(Dart_NativeArguments args) {
Namespace* namespc = Namespace::GetNamespace(args, 0);
Dart_Handle path = Dart_GetNativeArgument(args, 1);
+ OSError os_error;
bool result;
{
TypedDataScope data(path);
@@ -119,17 +142,22 @@
const char* name = data.GetCString();
result = Directory::Delete(namespc, name,
DartUtils::GetNativeBooleanArgument(args, 2));
+ if (!result) {
+ // Errors must be caught before TypedDataScope data is destroyed.
+ os_error.Reload();
+ }
}
if (result) {
Dart_SetBooleanReturnValue(args, true);
} else {
- Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+ Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
}
}
void FUNCTION_NAME(Directory_Rename)(Dart_NativeArguments args) {
Namespace* namespc = Namespace::GetNamespace(args, 0);
Dart_Handle path = Dart_GetNativeArgument(args, 1);
+ OSError os_error;
bool result;
{
TypedDataScope data(path);
@@ -137,11 +165,15 @@
const char* name = data.GetCString();
result = Directory::Rename(namespc, name,
DartUtils::GetNativeStringArgument(args, 2));
+ if (!result) {
+ // Errors must be caught before TypedDataScope data is destroyed.
+ os_error.Reload();
+ }
}
if (result) {
Dart_SetBooleanReturnValue(args, true);
} else {
- Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+ Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
}
}
diff --git a/runtime/bin/file.cc b/runtime/bin/file.cc
index 383b6bb..115bf3f 100644
--- a/runtime/bin/file.cc
+++ b/runtime/bin/file.cc
@@ -88,6 +88,7 @@
Namespace* namespc = Namespace::GetNamespace(args, 0);
Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
File* file = NULL;
+ OSError os_error;
{
TypedDataScope data(path_handle);
ASSERT(data.type() == Dart_TypedData_kUint8);
@@ -102,11 +103,15 @@
// files. Directories can be opened for reading using the posix
// 'open' call.
file = File::Open(namespc, filename, file_mode);
+ if (file == NULL) {
+ // Errors must be caught before TypedDataScope data is destroyed.
+ os_error.Reload();
+ }
}
if (file != NULL) {
Dart_SetIntegerReturnValue(args, reinterpret_cast<intptr_t>(file));
} else {
- Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+ Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
}
}
@@ -356,16 +361,21 @@
Namespace* namespc = Namespace::GetNamespace(args, 0);
Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
int64_t return_value;
+ OSError os_error;
{
TypedDataScope data(path_handle);
ASSERT(data.type() == Dart_TypedData_kUint8);
const char* path = data.GetCString();
return_value = File::LengthFromPath(namespc, path);
+ if (return_value < 0) {
+ // Errors must be caught before TypedDataScope data is destroyed.
+ os_error.Reload();
+ }
}
if (return_value >= 0) {
Dart_SetIntegerReturnValue(args, return_value);
} else {
- Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+ Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
}
}
@@ -373,16 +383,21 @@
Namespace* namespc = Namespace::GetNamespace(args, 0);
Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
int64_t return_value;
+ OSError os_error;
{
TypedDataScope data(path_handle);
ASSERT(data.type() == Dart_TypedData_kUint8);
const char* raw_name = data.GetCString();
return_value = File::LastModified(namespc, raw_name);
+ if (return_value < 0) {
+ // Errors must be caught before TypedDataScope data is destroyed.
+ os_error.Reload();
+ }
}
if (return_value >= 0) {
Dart_SetIntegerReturnValue(args, return_value * kMillisecondsPerSecond);
} else {
- Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+ Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
}
}
@@ -395,14 +410,19 @@
"The second argument must be a 64-bit int."));
}
bool result;
+ OSError os_error;
{
TypedDataScope data(path_handle);
ASSERT(data.type() == Dart_TypedData_kUint8);
const char* name = data.GetCString();
result = File::SetLastModified(namespc, name, millis);
+ if (!result) {
+ // Errors must be caught before TypedDataScope data is destroyed.
+ os_error.Reload();
+ }
}
if (!result) {
- Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+ Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
}
}
@@ -410,16 +430,21 @@
Namespace* namespc = Namespace::GetNamespace(args, 0);
Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
int64_t return_value;
+ OSError os_error;
{
TypedDataScope data(path_handle);
ASSERT(data.type() == Dart_TypedData_kUint8);
const char* name = data.GetCString();
return_value = File::LastAccessed(namespc, name);
+ if (return_value < 0) {
+ // Errors must be caught before TypedDataScope data is destroyed.
+ os_error.Reload();
+ }
}
if (return_value >= 0) {
Dart_SetIntegerReturnValue(args, return_value * kMillisecondsPerSecond);
} else {
- Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+ Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
}
}
@@ -432,14 +457,19 @@
"The second argument must be a 64-bit int."));
}
bool result;
+ OSError os_error;
{
TypedDataScope data(path_handle);
ASSERT(data.type() == Dart_TypedData_kUint8);
const char* name = data.GetCString();
result = File::SetLastAccessed(namespc, name, millis);
+ if (!result) {
+ // Errors must be caught before TypedDataScope data is destroyed.
+ os_error.Reload();
+ }
}
if (!result) {
- Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+ Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
}
}
@@ -480,16 +510,21 @@
Namespace* namespc = Namespace::GetNamespace(args, 0);
Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
bool result;
+ OSError os_error;
{
TypedDataScope data(path_handle);
ASSERT(data.type() == Dart_TypedData_kUint8);
const char* path = data.GetCString();
result = File::Create(namespc, path);
+ if (!result) {
+ // Errors must be caught before TypedDataScope data is destroyed.
+ os_error.Reload();
+ }
}
if (result) {
Dart_SetBooleanReturnValue(args, result);
} else {
- Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+ Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
}
}
@@ -497,15 +532,20 @@
Namespace* namespc = Namespace::GetNamespace(args, 0);
bool result;
Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
+ OSError os_error;
{
TypedDataScope data(path_handle);
ASSERT(data.type() == Dart_TypedData_kUint8);
const char* name = data.GetCString();
const char* target = DartUtils::GetNativeStringArgument(args, 2);
result = File::CreateLink(namespc, name, target);
+ if (!result) {
+ // Errors must be caught before TypedDataScope data is destroyed.
+ os_error.Reload();
+ }
}
if (!result) {
- Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+ Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
}
}
@@ -513,14 +553,19 @@
Namespace* namespc = Namespace::GetNamespace(args, 0);
Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
const char* target = NULL;
+ OSError os_error;
{
TypedDataScope data(path_handle);
ASSERT(data.type() == Dart_TypedData_kUint8);
const char* name = data.GetCString();
target = File::LinkTarget(namespc, name);
+ if (target == NULL) {
+ // Errors must be caught before TypedDataScope data is destroyed.
+ os_error.Reload();
+ }
}
if (target == NULL) {
- Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+ Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
} else {
Dart_SetReturnValue(args, DartUtils::NewString(target));
}
@@ -530,16 +575,21 @@
Namespace* namespc = Namespace::GetNamespace(args, 0);
bool result;
Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
+ OSError os_error;
{
TypedDataScope data(path_handle);
ASSERT(data.type() == Dart_TypedData_kUint8);
const char* path = data.GetCString();
result = File::Delete(namespc, path);
+ if (!result) {
+ // Errors must be caught before TypedDataScope data is destroyed.
+ os_error.Reload();
+ }
}
if (result) {
Dart_SetBooleanReturnValue(args, result);
} else {
- Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+ Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
}
}
@@ -547,16 +597,21 @@
Namespace* namespc = Namespace::GetNamespace(args, 0);
Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
bool result;
+ OSError os_error;
{
TypedDataScope data(path_handle);
ASSERT(data.type() == Dart_TypedData_kUint8);
const char* path = data.GetCString();
result = File::DeleteLink(namespc, path);
+ if (!result) {
+ // Errors must be caught before TypedDataScope data is destroyed.
+ os_error.Reload();
+ }
}
if (result) {
Dart_SetBooleanReturnValue(args, result);
} else {
- Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+ Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
}
}
@@ -564,17 +619,22 @@
Namespace* namespc = Namespace::GetNamespace(args, 0);
Dart_Handle old_path_handle = Dart_GetNativeArgument(args, 1);
bool result;
+ OSError os_error;
{
TypedDataScope old_path_data(old_path_handle);
ASSERT(old_path_data.type() == Dart_TypedData_kUint8);
const char* old_path = old_path_data.GetCString();
const char* new_path = DartUtils::GetNativeStringArgument(args, 2);
result = File::Rename(namespc, old_path, new_path);
+ if (!result) {
+ // Errors must be caught before TypedDataScope data is destroyed.
+ os_error.Reload();
+ }
}
if (result) {
Dart_SetBooleanReturnValue(args, result);
} else {
- Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+ Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
}
}
@@ -582,17 +642,22 @@
Namespace* namespc = Namespace::GetNamespace(args, 0);
Dart_Handle old_path_handle = Dart_GetNativeArgument(args, 1);
bool result;
+ OSError os_error;
{
TypedDataScope old_path_data(old_path_handle);
ASSERT(old_path_data.type() == Dart_TypedData_kUint8);
const char* old_path = old_path_data.GetCString();
const char* new_path = DartUtils::GetNativeStringArgument(args, 2);
result = File::RenameLink(namespc, old_path, new_path);
+ if (!result) {
+ // Errors must be caught before TypedDataScope data is destroyed.
+ os_error.Reload();
+ }
}
if (result) {
Dart_SetBooleanReturnValue(args, result);
} else {
- Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+ Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
}
}
@@ -600,17 +665,22 @@
Namespace* namespc = Namespace::GetNamespace(args, 0);
Dart_Handle old_path_handle = Dart_GetNativeArgument(args, 1);
bool result;
+ OSError os_error;
{
TypedDataScope old_path_data(old_path_handle);
ASSERT(old_path_data.type() == Dart_TypedData_kUint8);
const char* old_path = old_path_data.GetCString();
const char* new_path = DartUtils::GetNativeStringArgument(args, 2);
result = File::Copy(namespc, old_path, new_path);
+ if (!result) {
+ // Errors must be caught before TypedDataScope data is destroyed.
+ os_error.Reload();
+ }
}
if (result) {
Dart_SetBooleanReturnValue(args, result);
} else {
- Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+ Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
}
}
@@ -618,16 +688,21 @@
Namespace* namespc = Namespace::GetNamespace(args, 0);
Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
const char* path = NULL;
+ OSError os_error;
{
TypedDataScope data(path_handle);
ASSERT(data.type() == Dart_TypedData_kUint8);
const char* str = data.GetCString();
path = File::GetCanonicalPath(namespc, str);
+ if (path == NULL) {
+ // Errors must be caught before TypedDataScope data is destroyed.
+ os_error.Reload();
+ }
}
if (path != NULL) {
Dart_SetReturnValue(args, DartUtils::NewString(path));
} else {
- Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+ Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
}
}
diff --git a/runtime/bin/utils.h b/runtime/bin/utils.h
index 234a969..8d4ab44 100644
--- a/runtime/bin/utils.h
+++ b/runtime/bin/utils.h
@@ -27,6 +27,8 @@
}
virtual ~OSError() { free(message_); }
+ void Reload();
+
SubSystem sub_system() { return sub_system_; }
int code() { return code_; }
char* message() { return message_; }
diff --git a/runtime/bin/utils_android.cc b/runtime/bin/utils_android.cc
index a705997..d448efe 100644
--- a/runtime/bin/utils_android.cc
+++ b/runtime/bin/utils_android.cc
@@ -18,6 +18,10 @@
namespace bin {
OSError::OSError() : sub_system_(kSystem), code_(0), message_(NULL) {
+ Reload();
+}
+
+void OSError::Reload() {
set_sub_system(kSystem);
set_code(errno);
const int kBufferSize = 1024;
diff --git a/runtime/bin/utils_fuchsia.cc b/runtime/bin/utils_fuchsia.cc
index e1f3dca..ad6e418 100644
--- a/runtime/bin/utils_fuchsia.cc
+++ b/runtime/bin/utils_fuchsia.cc
@@ -17,6 +17,10 @@
namespace bin {
OSError::OSError() : sub_system_(kSystem), code_(0), message_(NULL) {
+ Reload();
+}
+
+void OSError::Reload() {
set_sub_system(kSystem);
set_code(errno);
const int kBufferSize = 1024;
diff --git a/runtime/bin/utils_linux.cc b/runtime/bin/utils_linux.cc
index 3e27c0c..6c7e9b7 100644
--- a/runtime/bin/utils_linux.cc
+++ b/runtime/bin/utils_linux.cc
@@ -18,6 +18,10 @@
namespace bin {
OSError::OSError() : sub_system_(kSystem), code_(0), message_(NULL) {
+ Reload();
+}
+
+void OSError::Reload() {
set_sub_system(kSystem);
set_code(errno);
const int kBufferSize = 1024;
diff --git a/runtime/bin/utils_macos.cc b/runtime/bin/utils_macos.cc
index bec7153..8d3ed43 100644
--- a/runtime/bin/utils_macos.cc
+++ b/runtime/bin/utils_macos.cc
@@ -21,6 +21,10 @@
namespace bin {
OSError::OSError() : sub_system_(kSystem), code_(0), message_(NULL) {
+ Reload();
+}
+
+void OSError::Reload() {
set_sub_system(kSystem);
set_code(errno);
const int kBufferSize = 1024;
diff --git a/runtime/bin/utils_win.cc b/runtime/bin/utils_win.cc
index 99e9fb8..bc5f934 100644
--- a/runtime/bin/utils_win.cc
+++ b/runtime/bin/utils_win.cc
@@ -32,6 +32,10 @@
}
OSError::OSError() : sub_system_(kSystem), code_(0), message_(NULL) {
+ Reload();
+}
+
+void OSError::Reload() {
set_code(GetLastError());
static const int kMaxMessageLength = 256;