diff options
Diffstat (limited to 'externals/breakpad/src/common/tests/file_utils.cc')
-rw-r--r-- | externals/breakpad/src/common/tests/file_utils.cc | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/externals/breakpad/src/common/tests/file_utils.cc b/externals/breakpad/src/common/tests/file_utils.cc new file mode 100644 index 0000000000..84a228095e --- /dev/null +++ b/externals/breakpad/src/common/tests/file_utils.cc @@ -0,0 +1,160 @@ +// Copyright 2011 Google LLC +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google LLC nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// file_utils.cc: Implement utility functions for file manipulation. +// See file_utils.h for details. + +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <sys/stat.h> +#include <unistd.h> + +#include "common/linux/eintr_wrapper.h" +#include "common/tests/file_utils.h" + +namespace google_breakpad { + +bool CopyFile(const char* from_path, const char* to_path) { + int infile = HANDLE_EINTR(open(from_path, O_RDONLY)); + if (infile < 0) { + perror("open"); + return false; + } + + int outfile = HANDLE_EINTR(creat(to_path, 0666)); + if (outfile < 0) { + perror("creat"); + if (IGNORE_EINTR(close(infile)) < 0) { + perror("close"); + } + return false; + } + + char buffer[1024]; + bool result = true; + + while (result) { + ssize_t bytes_read = HANDLE_EINTR(read(infile, buffer, sizeof(buffer))); + if (bytes_read < 0) { + perror("read"); + result = false; + break; + } + if (bytes_read == 0) + break; + ssize_t bytes_written_per_read = 0; + do { + ssize_t bytes_written_partial = HANDLE_EINTR(write( + outfile, + &buffer[bytes_written_per_read], + bytes_read - bytes_written_per_read)); + if (bytes_written_partial < 0) { + perror("write"); + result = false; + break; + } + bytes_written_per_read += bytes_written_partial; + } while (bytes_written_per_read < bytes_read); + } + + if (IGNORE_EINTR(close(infile)) == -1) { + perror("close"); + result = false; + } + if (IGNORE_EINTR(close(outfile)) == -1) { + perror("close"); + result = false; + } + + return result; +} + +bool CopyFile(const std::string& from_path, const std::string& to_path) { + return CopyFile(from_path.c_str(), to_path.c_str()); +} + +bool ReadFile(const char* path, void* buffer, ssize_t* buffer_size) { + int fd = HANDLE_EINTR(open(path, O_RDONLY)); + if (fd == -1) { + perror("open"); + return false; + } + + bool ok = true; + if (buffer && buffer_size && *buffer_size > 0) { + memset(buffer, 0, sizeof(*buffer_size)); + *buffer_size = HANDLE_EINTR(read(fd, buffer, *buffer_size)); + if (*buffer_size == -1) { + perror("read"); + ok = false; + } + } + if (IGNORE_EINTR(close(fd)) == -1) { + perror("close"); + ok = false; + } + return ok; +} + +bool WriteFile(const char* path, const void* buffer, size_t buffer_size) { + int fd = HANDLE_EINTR(open(path, O_CREAT | O_TRUNC | O_WRONLY, S_IRWXU)); + if (fd == -1) { + perror("open"); + return false; + } + + bool ok = true; + if (buffer) { + size_t bytes_written_total = 0; + ssize_t bytes_written_partial = 0; + const char* data = reinterpret_cast<const char*>(buffer); + while (bytes_written_total < buffer_size) { + bytes_written_partial = + HANDLE_EINTR(write(fd, data + bytes_written_total, + buffer_size - bytes_written_total)); + if (bytes_written_partial < 0) { + perror("write"); + ok = false; + break; + } + bytes_written_total += bytes_written_partial; + } + } + if (IGNORE_EINTR(close(fd)) == -1) { + perror("close"); + ok = false; + } + return ok; +} + +} // namespace google_breakpad |