da9dd59eb0
This is a reland ofaf4a3112c4Original change's description: > Reland "fix hanging of write on Windows" > > This is a reland ofeb075dcc21> > Original change's description: > > fix hanging of write on Windows > > > > When using File::Write(), Var size in int64_t is casted to DWORD(unsigned long). When Var size is out of DWORD range, casted value will be zero. Before calling into File::Write() on Windows, validate the size. > > > > Bug: https://github.com/dart-lang/sdk/issues/40339 > > Change-Id: I36fade62dfa3025f418405cb3e45c286dd6b7db1 > > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/134440 > > Reviewed-by: Zach Anderson <zra@google.com> > > Commit-Queue: Zichang Guo <zichangguo@google.com> > > Bug: https://github.com/dart-lang/sdk/issues/40339 > Change-Id: I5a07c58709c62b996a55a76272636602dc80e20d > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/134783 > Commit-Queue: Zichang Guo <zichangguo@google.com> > Reviewed-by: Siva Annamalai <asiva@google.com> Bug: https://github.com/dart-lang/sdk/issues/40339 Change-Id: I78e4bd993271cdeac9db5a1d005ae5be0f2891c9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/135340 Reviewed-by: Zach Anderson <zra@google.com> Commit-Queue: Zichang Guo <zichangguo@google.com>
108 lines
3.2 KiB
C++
108 lines
3.2 KiB
C++
// Copyright (c) 2016, 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.
|
|
|
|
#include "bin/file.h"
|
|
|
|
#include "bin/builtin.h"
|
|
#include "bin/dartutils.h"
|
|
#include "bin/io_buffer.h"
|
|
#include "bin/utils.h"
|
|
|
|
#include "include/bin/dart_io_api.h"
|
|
#include "include/dart_api.h"
|
|
#include "include/dart_tools_api.h"
|
|
|
|
namespace dart {
|
|
namespace bin {
|
|
|
|
// Are we capturing output from stdout for the VM service?
|
|
static bool capture_stdout = false;
|
|
|
|
// Are we capturing output from stderr for the VM service?
|
|
static bool capture_stderr = false;
|
|
|
|
void SetCaptureStdout(bool value) {
|
|
capture_stdout = value;
|
|
}
|
|
|
|
void SetCaptureStderr(bool value) {
|
|
capture_stderr = value;
|
|
}
|
|
|
|
bool ShouldCaptureStdout() {
|
|
return capture_stdout;
|
|
}
|
|
|
|
bool ShouldCaptureStderr() {
|
|
return capture_stderr;
|
|
}
|
|
|
|
bool File::ReadFully(void* buffer, int64_t num_bytes) {
|
|
int64_t remaining = num_bytes;
|
|
char* current_buffer = reinterpret_cast<char*>(buffer);
|
|
while (remaining > 0) {
|
|
int64_t bytes_read = Read(current_buffer, remaining);
|
|
if (bytes_read <= 0) {
|
|
return false;
|
|
}
|
|
remaining -= bytes_read; // Reduce the number of remaining bytes.
|
|
current_buffer += bytes_read; // Move the buffer forward.
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool File::WriteFully(const void* buffer, int64_t num_bytes) {
|
|
int64_t remaining = num_bytes;
|
|
const char* current_buffer = reinterpret_cast<const char*>(buffer);
|
|
while (remaining > 0) {
|
|
// On Windows, narrowing conversion from int64_t to DWORD will cause
|
|
// unexpected error.
|
|
// On MacOS, a single write() with more than kMaxInt32 will have
|
|
// "invalid argument" error.
|
|
// Therefore, limit the size for single write.
|
|
int64_t byte_to_write = remaining > kMaxInt32 ? kMaxInt32 : remaining;
|
|
int64_t bytes_written = Write(current_buffer, byte_to_write);
|
|
if (bytes_written < 0) {
|
|
return false;
|
|
}
|
|
remaining -= bytes_written; // Reduce the number of remaining bytes.
|
|
current_buffer += bytes_written; // Move the buffer forward.
|
|
}
|
|
if (capture_stdout || capture_stderr) {
|
|
intptr_t fd = GetFD();
|
|
if ((fd == STDOUT_FILENO) && capture_stdout) {
|
|
Dart_ServiceSendDataEvent("Stdout", "WriteEvent",
|
|
reinterpret_cast<const uint8_t*>(buffer),
|
|
num_bytes);
|
|
} else if ((fd == STDERR_FILENO) && capture_stderr) {
|
|
Dart_ServiceSendDataEvent("Stderr", "WriteEvent",
|
|
reinterpret_cast<const uint8_t*>(buffer),
|
|
num_bytes);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
File::FileOpenMode File::DartModeToFileMode(DartFileOpenMode mode) {
|
|
ASSERT((mode == File::kDartRead) || (mode == File::kDartWrite) ||
|
|
(mode == File::kDartAppend) || (mode == File::kDartWriteOnly) ||
|
|
(mode == File::kDartWriteOnlyAppend));
|
|
if (mode == File::kDartWrite) {
|
|
return File::kWriteTruncate;
|
|
}
|
|
if (mode == File::kDartAppend) {
|
|
return File::kWrite;
|
|
}
|
|
if (mode == File::kDartWriteOnly) {
|
|
return File::kWriteOnlyTruncate;
|
|
}
|
|
if (mode == File::kDartWriteOnlyAppend) {
|
|
return File::kWriteOnly;
|
|
}
|
|
return File::kRead;
|
|
}
|
|
|
|
} // namespace bin
|
|
} // namespace dart
|