8303942: os::write should write completely
Reviewed-by: coleenp, iklam, dholmes, mgronlun
This commit is contained in:
parent
ab241b3428
commit
bddf48380e
@ -771,9 +771,9 @@ FILE* os::fdopen(int fd, const char* mode) {
|
|||||||
return ::fdopen(fd, mode);
|
return ::fdopen(fd, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t os::write(int fd, const void *buf, unsigned int nBytes) {
|
ssize_t os::pd_write(int fd, const void *buf, size_t nBytes) {
|
||||||
ssize_t res;
|
ssize_t res;
|
||||||
RESTARTABLE(::write(fd, buf, (size_t) nBytes), res);
|
RESTARTABLE(::write(fd, buf, nBytes), res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,33 +97,21 @@ static void save_memory_to_file(char* addr, size_t size) {
|
|||||||
|
|
||||||
RESTARTABLE(os::open(destfile, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR), fd);
|
RESTARTABLE(os::open(destfile, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR), fd);
|
||||||
if (fd == OS_ERR) {
|
if (fd == OS_ERR) {
|
||||||
if (PrintMiscellaneous && Verbose) {
|
warning("Could not create Perfdata save file: %s: %s\n",
|
||||||
warning("Could not create Perfdata save file: %s: %s\n",
|
destfile, os::strerror(errno));
|
||||||
destfile, os::strerror(errno));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ssize_t result;
|
ssize_t result;
|
||||||
|
|
||||||
for (size_t remaining = size; remaining > 0;) {
|
bool successful_write = os::write(fd, addr, size);
|
||||||
|
if (!successful_write) {
|
||||||
result = os::write(fd, addr, remaining);
|
warning("Could not write Perfdata save file: %s: %s\n",
|
||||||
if (result == OS_ERR) {
|
destfile, os::strerror(errno));
|
||||||
if (PrintMiscellaneous && Verbose) {
|
|
||||||
warning("Could not write Perfdata save file: %s: %s\n",
|
|
||||||
destfile, os::strerror(errno));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
remaining -= (size_t)result;
|
|
||||||
addr += result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
result = ::close(fd);
|
result = ::close(fd);
|
||||||
if (PrintMiscellaneous && Verbose) {
|
if (result == OS_ERR) {
|
||||||
if (result == OS_ERR) {
|
warning("Could not close %s: %s\n", destfile, os::strerror(errno));
|
||||||
warning("Could not close %s: %s\n", destfile, os::strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FREE_C_HEAP_ARRAY(char, destfile);
|
FREE_C_HEAP_ARRAY(char, destfile);
|
||||||
@ -961,11 +949,11 @@ static int create_sharedmem_file(const char* dirname, const char* filename, size
|
|||||||
int zero_int = 0;
|
int zero_int = 0;
|
||||||
result = (int)os::seek_to_file_offset(fd, (jlong)(seekpos));
|
result = (int)os::seek_to_file_offset(fd, (jlong)(seekpos));
|
||||||
if (result == -1 ) break;
|
if (result == -1 ) break;
|
||||||
result = os::write(fd, &zero_int, 1);
|
if (!os::write(fd, &zero_int, 1)) {
|
||||||
if (result != 1) {
|
|
||||||
if (errno == ENOSPC) {
|
if (errno == ENOSPC) {
|
||||||
warning("Insufficient space for shared memory file:\n %s\nTry using the -Djava.io.tmpdir= option to select an alternate temp location.\n", filename);
|
warning("Insufficient space for shared memory file:\n %s\nTry using the -Djava.io.tmpdir= option to select an alternate temp location.\n", filename);
|
||||||
}
|
}
|
||||||
|
result = OS_ERR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4775,8 +4775,19 @@ FILE* os::fdopen(int fd, const char* mode) {
|
|||||||
return ::_fdopen(fd, mode);
|
return ::_fdopen(fd, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t os::write(int fd, const void *buf, unsigned int nBytes) {
|
ssize_t os::pd_write(int fd, const void *buf, size_t nBytes) {
|
||||||
return ::write(fd, buf, nBytes);
|
ssize_t original_len = (ssize_t)nBytes;
|
||||||
|
while (nBytes > 0) {
|
||||||
|
unsigned int len = nBytes > INT_MAX ? INT_MAX : (unsigned int)nBytes;
|
||||||
|
// On Windows, ::write takes 'unsigned int' no of bytes, so nBytes should be split if larger.
|
||||||
|
ssize_t written_bytes = ::write(fd, buf, len);
|
||||||
|
if (written_bytes < 0) {
|
||||||
|
return OS_ERR;
|
||||||
|
}
|
||||||
|
nBytes -= written_bytes;
|
||||||
|
buf = (char *)buf + written_bytes;
|
||||||
|
}
|
||||||
|
return original_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void os::exit(int num) {
|
void os::exit(int num) {
|
||||||
|
@ -1646,8 +1646,7 @@ size_t FileMapInfo::write_heap_region(ArchiveHeapInfo* heap_info) {
|
|||||||
|
|
||||||
void FileMapInfo::write_bytes(const void* buffer, size_t nbytes) {
|
void FileMapInfo::write_bytes(const void* buffer, size_t nbytes) {
|
||||||
assert(_file_open, "must be");
|
assert(_file_open, "must be");
|
||||||
ssize_t n = os::write(_fd, buffer, (unsigned int)nbytes);
|
if (!os::write(_fd, buffer, nbytes)) {
|
||||||
if (n < 0 || (size_t)n != nbytes) {
|
|
||||||
// If the shared archive is corrupted, close it and remove it.
|
// If the shared archive is corrupted, close it and remove it.
|
||||||
close();
|
close();
|
||||||
remove(_full_path);
|
remove(_full_path);
|
||||||
|
@ -380,13 +380,17 @@ static void write_repository_files(const RepositoryIterator& iterator, char* con
|
|||||||
const ssize_t read_result = os::read_at(current_fd, copy_block, (int)block_size, bytes_read);
|
const ssize_t read_result = os::read_at(current_fd, copy_block, (int)block_size, bytes_read);
|
||||||
if (-1 == read_result) {
|
if (-1 == read_result) {
|
||||||
log_info(jfr)( // For user, should not be "jfr, system"
|
log_info(jfr)( // For user, should not be "jfr, system"
|
||||||
"Unable to recover JFR data");
|
"Unable to recover JFR data, read failed.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bytes_read += (int64_t)read_result;
|
bytes_read += (int64_t)read_result;
|
||||||
assert(bytes_read - bytes_written <= (int64_t)block_size, "invariant");
|
assert(bytes_read - bytes_written <= (int64_t)block_size, "invariant");
|
||||||
bytes_written += (int64_t)os::write(emergency_fd, copy_block, bytes_read - bytes_written);
|
if (!os::write(emergency_fd, copy_block, bytes_read - bytes_written)) {
|
||||||
assert(bytes_read == bytes_written, "invariant");
|
log_info(jfr)( // For user, should not be "jfr, system"
|
||||||
|
"Unable to recover JFR data, write failed.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bytes_written = bytes_read;
|
||||||
}
|
}
|
||||||
::close(current_fd);
|
::close(current_fd);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -76,14 +76,14 @@ inline void StreamWriterHost<Adapter, AP>::write_bytes(const u1* buf, intptr_t l
|
|||||||
assert(len >= 0, "invariant");
|
assert(len >= 0, "invariant");
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
const unsigned int nBytes = len > INT_MAX ? INT_MAX : (unsigned int)len;
|
const unsigned int nBytes = len > INT_MAX ? INT_MAX : (unsigned int)len;
|
||||||
const ssize_t num_written = os::write(_fd, buf, nBytes);
|
const bool successful_write = os::write(_fd, buf, nBytes);
|
||||||
if (errno == ENOSPC) {
|
if (!successful_write && errno == ENOSPC) {
|
||||||
JfrJavaSupport::abort("Failed to write to jfr stream because no space left on device", false);
|
JfrJavaSupport::abort("Failed to write to jfr stream because no space left on device", false);
|
||||||
}
|
}
|
||||||
guarantee(num_written > 0, "Nothing got written, or os::write() failed");
|
guarantee(successful_write, "Not all the bytes got written, or os::write() failed");
|
||||||
_stream_pos += num_written;
|
_stream_pos += nBytes;
|
||||||
len -= num_written;
|
len -= nBytes;
|
||||||
buf += num_written;
|
buf += nBytes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2897,7 +2897,7 @@ void jio_print(const char* s, size_t len) {
|
|||||||
jio_fprintf(defaultStream::output_stream(), "%.*s", (int)len, s);
|
jio_fprintf(defaultStream::output_stream(), "%.*s", (int)len, s);
|
||||||
} else {
|
} else {
|
||||||
// Make an unused local variable to avoid warning from gcc compiler.
|
// Make an unused local variable to avoid warning from gcc compiler.
|
||||||
ssize_t count = os::write(defaultStream::output_fd(), s, (int)len);
|
bool dummy = os::write(defaultStream::output_fd(), s, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1383,6 +1383,22 @@ bool os::file_exists(const char* filename) {
|
|||||||
return os::stat(filename, &statbuf) == 0;
|
return os::stat(filename, &statbuf) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool os::write(int fd, const void *buf, size_t nBytes) {
|
||||||
|
ssize_t res;
|
||||||
|
|
||||||
|
while (nBytes > 0) {
|
||||||
|
res = pd_write(fd, buf, nBytes);
|
||||||
|
if (res == OS_ERR) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
buf = (void *)((char *)buf + nBytes);
|
||||||
|
nBytes -= res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Splits a path, based on its separator, the number of
|
// Splits a path, based on its separator, the number of
|
||||||
// elements is returned back in "elements".
|
// elements is returned back in "elements".
|
||||||
// file_name_length is used as a modifier for each path's
|
// file_name_length is used as a modifier for each path's
|
||||||
|
@ -229,6 +229,8 @@ class os: AllStatic {
|
|||||||
// Get summary strings for system information in buffer provided
|
// Get summary strings for system information in buffer provided
|
||||||
static void get_summary_cpu_info(char* buf, size_t buflen);
|
static void get_summary_cpu_info(char* buf, size_t buflen);
|
||||||
static void get_summary_os_info(char* buf, size_t buflen);
|
static void get_summary_os_info(char* buf, size_t buflen);
|
||||||
|
// Returns number of bytes written on success, OS_ERR on failure.
|
||||||
|
static ssize_t pd_write(int fd, const void *buf, size_t nBytes);
|
||||||
|
|
||||||
static void initialize_initial_active_processor_count();
|
static void initialize_initial_active_processor_count();
|
||||||
|
|
||||||
@ -650,7 +652,8 @@ class os: AllStatic {
|
|||||||
//File i/o operations
|
//File i/o operations
|
||||||
|
|
||||||
static ssize_t read_at(int fd, void *buf, unsigned int nBytes, jlong offset);
|
static ssize_t read_at(int fd, void *buf, unsigned int nBytes, jlong offset);
|
||||||
static ssize_t write(int fd, const void *buf, unsigned int nBytes);
|
// Writes the bytes completely. Returns true on success, false otherwise.
|
||||||
|
static bool write(int fd, const void *buf, size_t nBytes);
|
||||||
|
|
||||||
// Reading directories.
|
// Reading directories.
|
||||||
static DIR* opendir(const char* dirname);
|
static DIR* opendir(const char* dirname);
|
||||||
|
@ -55,14 +55,8 @@ char const* FileWriter::write_buf(char* buf, ssize_t size) {
|
|||||||
assert(_fd >= 0, "Must be open");
|
assert(_fd >= 0, "Must be open");
|
||||||
assert(size > 0, "Must write at least one byte");
|
assert(size > 0, "Must write at least one byte");
|
||||||
|
|
||||||
while (size > 0) {
|
if (!os::write(_fd, buf, (size_t)size)) {
|
||||||
ssize_t n = os::write(_fd, buf, (uint) size);
|
return os::strerror(errno);
|
||||||
if (n <= 0) {
|
|
||||||
return os::strerror(errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
buf += n;
|
|
||||||
size -= n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
Loading…
Reference in New Issue
Block a user