forked from OSchip/llvm-project
[ASan/Win] Add more support for file operations
llvm-svn: 234494
This commit is contained in:
parent
359b105745
commit
007435c1b7
|
@ -804,7 +804,7 @@ void CovPrepareForSandboxing(__sanitizer_sandbox_arguments *args) {
|
||||||
if (!cov_sandboxed) return;
|
if (!cov_sandboxed) return;
|
||||||
cov_max_block_size = args->coverage_max_block_size;
|
cov_max_block_size = args->coverage_max_block_size;
|
||||||
if (args->coverage_fd >= 0) {
|
if (args->coverage_fd >= 0) {
|
||||||
cov_fd = args->coverage_fd;
|
cov_fd = (fd_t)args->coverage_fd;
|
||||||
} else {
|
} else {
|
||||||
InternalScopedString path(kMaxPathLength);
|
InternalScopedString path(kMaxPathLength);
|
||||||
// Pre-open the file now. The sandbox won't allow us to do it later.
|
// Pre-open the file now. The sandbox won't allow us to do it later.
|
||||||
|
|
|
@ -80,8 +80,15 @@ typedef signed char s8;
|
||||||
typedef signed short s16; // NOLINT
|
typedef signed short s16; // NOLINT
|
||||||
typedef signed int s32;
|
typedef signed int s32;
|
||||||
typedef signed long long s64; // NOLINT
|
typedef signed long long s64; // NOLINT
|
||||||
|
#if SANITIZER_WINDOWS
|
||||||
|
// On Windows, files are HANDLE, which is a synonim of void*.
|
||||||
|
// Use void* to avoid including <windows.h> everywhere.
|
||||||
|
typedef void* fd_t;
|
||||||
|
typedef unsigned error_t;
|
||||||
|
#else
|
||||||
typedef int fd_t;
|
typedef int fd_t;
|
||||||
typedef int error_t;
|
typedef int error_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
// WARNING: OFF_T may be different from OS type off_t, depending on the value of
|
// WARNING: OFF_T may be different from OS type off_t, depending on the value of
|
||||||
// _FILE_OFFSET_BITS. This definition of OFF_T matches the ABI of system calls
|
// _FILE_OFFSET_BITS. This definition of OFF_T matches the ABI of system calls
|
||||||
|
|
|
@ -58,10 +58,10 @@ int internal_snprintf(char *buffer, uptr length, const char *format, ...);
|
||||||
bool mem_is_zero(const char *mem, uptr size);
|
bool mem_is_zero(const char *mem, uptr size);
|
||||||
|
|
||||||
// I/O
|
// I/O
|
||||||
const fd_t kInvalidFd = -1;
|
const fd_t kInvalidFd = (fd_t)-1;
|
||||||
const fd_t kStdinFd = 0;
|
const fd_t kStdinFd = 0;
|
||||||
const fd_t kStdoutFd = 1;
|
const fd_t kStdoutFd = (fd_t)1;
|
||||||
const fd_t kStderrFd = 2;
|
const fd_t kStderrFd = (fd_t)2;
|
||||||
|
|
||||||
uptr internal_ftruncate(fd_t fd, uptr size);
|
uptr internal_ftruncate(fd_t fd, uptr size);
|
||||||
|
|
||||||
|
|
|
@ -396,11 +396,17 @@ static __declspec(allocate(".CRT$XID")) int (*__run_atexit)() = RunAtexit;
|
||||||
|
|
||||||
// ------------------ sanitizer_libc.h
|
// ------------------ sanitizer_libc.h
|
||||||
fd_t OpenFile(const char *filename, FileAccessMode mode, error_t *last_error) {
|
fd_t OpenFile(const char *filename, FileAccessMode mode, error_t *last_error) {
|
||||||
UNIMPLEMENTED();
|
if (mode != WrOnly)
|
||||||
|
UNIMPLEMENTED();
|
||||||
|
fd_t res = CreateFile(filename, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS,
|
||||||
|
FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||||
|
CHECK(res != kStdoutFd || kStdoutFd == kInvalidFd);
|
||||||
|
CHECK(res != kStderrFd || kStderrFd == kInvalidFd);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CloseFile(fd_t fd) {
|
void CloseFile(fd_t fd) {
|
||||||
UNIMPLEMENTED();
|
CloseHandle(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReadFromFile(fd_t fd, void *buff, uptr buff_size, uptr *bytes_read,
|
bool ReadFromFile(fd_t fd, void *buff, uptr buff_size, uptr *bytes_read,
|
||||||
|
@ -415,58 +421,25 @@ bool SupportsColoredOutput(fd_t fd) {
|
||||||
|
|
||||||
bool WriteToFile(fd_t fd, const void *buff, uptr buff_size, uptr *bytes_written,
|
bool WriteToFile(fd_t fd, const void *buff, uptr buff_size, uptr *bytes_written,
|
||||||
error_t *error_p) {
|
error_t *error_p) {
|
||||||
if (fd != kStderrFd)
|
CHECK(fd != kInvalidFd);
|
||||||
UNIMPLEMENTED();
|
|
||||||
|
|
||||||
static HANDLE output_stream = 0;
|
if (fd == kStdoutFd) {
|
||||||
// Abort immediately if we know printing is not possible.
|
fd = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
if (output_stream == INVALID_HANDLE_VALUE) {
|
if (fd == 0) fd = kInvalidFd;
|
||||||
if (error_p) *error_p = ERROR_INVALID_HANDLE;
|
} else if (fd == kStderrFd) {
|
||||||
return false;
|
fd = GetStdHandle(STD_ERROR_HANDLE);
|
||||||
}
|
if (fd == 0) fd = kInvalidFd;
|
||||||
|
|
||||||
// If called for the first time, try to use stderr to output stuff,
|
|
||||||
// falling back to stdout if anything goes wrong.
|
|
||||||
bool fallback_to_stdout = false;
|
|
||||||
if (output_stream == 0) {
|
|
||||||
output_stream = GetStdHandle(STD_ERROR_HANDLE);
|
|
||||||
// We don't distinguish "no such handle" from error.
|
|
||||||
if (output_stream == 0)
|
|
||||||
output_stream = INVALID_HANDLE_VALUE;
|
|
||||||
|
|
||||||
if (output_stream == INVALID_HANDLE_VALUE) {
|
|
||||||
// Retry with stdout?
|
|
||||||
output_stream = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
||||||
if (output_stream == 0)
|
|
||||||
output_stream = INVALID_HANDLE_VALUE;
|
|
||||||
if (output_stream == INVALID_HANDLE_VALUE) {
|
|
||||||
if (error_p) *error_p = ERROR_INVALID_HANDLE;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Successfully got an stderr handle. However, if WriteFile() fails,
|
|
||||||
// we can still try to fallback to stdout.
|
|
||||||
fallback_to_stdout = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD internal_bytes_written;
|
DWORD internal_bytes_written;
|
||||||
if (WriteFile(output_stream, buff, buff_size, &internal_bytes_written, 0)) {
|
if (fd == kInvalidFd ||
|
||||||
|
WriteFile(fd, buff, buff_size, &internal_bytes_written, 0)) {
|
||||||
|
if (error_p) *error_p = GetLastError();
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
if (bytes_written) *bytes_written = internal_bytes_written;
|
if (bytes_written) *bytes_written = internal_bytes_written;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-try with stdout if using a valid stderr handle fails.
|
|
||||||
if (fallback_to_stdout) {
|
|
||||||
output_stream = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
||||||
if (output_stream == 0)
|
|
||||||
output_stream = INVALID_HANDLE_VALUE;
|
|
||||||
if (output_stream != INVALID_HANDLE_VALUE)
|
|
||||||
return WriteToFile(fd, buff, buff_size, bytes_written, error_p);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error_p) *error_p = GetLastError();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenameFile(const char *oldpath, const char *newpath, error_t *error_p) {
|
bool RenameFile(const char *oldpath, const char *newpath, error_t *error_p) {
|
||||||
|
|
Loading…
Reference in New Issue