186cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// Copyright (c) 2011, Google Inc.
286cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// All rights reserved.
386cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org//
486cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// Redistribution and use in source and binary forms, with or without
586cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// modification, are permitted provided that the following conditions are
686cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// met:
786cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org//
886cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org//     * Redistributions of source code must retain the above copyright
986cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// notice, this list of conditions and the following disclaimer.
1086cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org//     * Redistributions in binary form must reproduce the above
1186cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// copyright notice, this list of conditions and the following disclaimer
1286cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// in the documentation and/or other materials provided with the
1386cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// distribution.
1486cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org//     * Neither the name of Google Inc. nor the names of its
1586cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// contributors may be used to endorse or promote products derived from
1686cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// this software without specific prior written permission.
1786cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org//
1886cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1986cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2086cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2186cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2286cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2386cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2486cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2586cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2686cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2786cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2886cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2986cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org
3086cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// file_utils.cc: Implement utility functions for file manipulation.
3186cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org// See file_utils.h for details.
3286cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org
3386cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org#include <fcntl.h>
3486cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org#include <stdio.h>
3586cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org#include <string.h>
364ac3c240983991b6358baad732e2fbe3fd4f7245digit@chromium.org#include <sys/stat.h>
3786cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org#include <unistd.h>
3886cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org
3986cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org#include "common/linux/eintr_wrapper.h"
4086cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org#include "common/tests/file_utils.h"
4186cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org
4286cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.orgnamespace google_breakpad {
4386cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org
4413de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.orgbool CopyFile(const char* from_path, const char* to_path) {
4513de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org  int infile = HANDLE_EINTR(open(from_path, O_RDONLY));
4613de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org  if (infile < 0) {
4713de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org    perror("open");
4813de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org    return false;
4913de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org  }
5013de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org
5113de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org  int outfile = HANDLE_EINTR(creat(to_path, 0666));
5213de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org  if (outfile < 0) {
5313de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org    perror("creat");
541a5016d36e53e2f1f7bebbcd1a7a8e4d667182d4mark@chromium.org    if (IGNORE_EINTR(close(infile)) < 0) {
5513de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org      perror("close");
5613de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org    }
5713de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org    return false;
5813de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org  }
5913de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org
6013de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org  char buffer[1024];
6113de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org  bool result = true;
6213de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org
6313de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org  while (result) {
6413de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org    ssize_t bytes_read = HANDLE_EINTR(read(infile, buffer, sizeof(buffer)));
6513de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org    if (bytes_read < 0) {
6613de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org      perror("read");
6713de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org      result = false;
6813de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org      break;
6913de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org    }
7013de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org    if (bytes_read == 0)
7113de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org      break;
7213de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org    ssize_t bytes_written_per_read = 0;
7313de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org    do {
7413de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org      ssize_t bytes_written_partial = HANDLE_EINTR(write(
7513de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org          outfile,
7613de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org          &buffer[bytes_written_per_read],
7713de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org          bytes_read - bytes_written_per_read));
7813de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org      if (bytes_written_partial < 0) {
7913de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org        perror("write");
8013de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org        result = false;
8113de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org        break;
8213de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org      }
8313de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org      bytes_written_per_read += bytes_written_partial;
8413de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org    } while (bytes_written_per_read < bytes_read);
8513de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org  }
8613de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org
871a5016d36e53e2f1f7bebbcd1a7a8e4d667182d4mark@chromium.org  if (IGNORE_EINTR(close(infile)) == -1) {
8813de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org    perror("close");
8913de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org    result = false;
9013de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org  }
911a5016d36e53e2f1f7bebbcd1a7a8e4d667182d4mark@chromium.org  if (IGNORE_EINTR(close(outfile)) == -1) {
9213de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org    perror("close");
9313de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org    result = false;
9413de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org  }
9513de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org
9613de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org  return result;
9713de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org}
9813de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org
9986cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.orgbool ReadFile(const char* path, void* buffer, ssize_t* buffer_size) {
10086cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org  int fd = HANDLE_EINTR(open(path, O_RDONLY));
10186cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org  if (fd == -1) {
10286cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org    perror("open");
10386cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org    return false;
10486cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org  }
10586cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org
10686cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org  bool ok = true;
10786cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org  if (buffer && buffer_size && *buffer_size > 0) {
10886cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org    memset(buffer, 0, sizeof(*buffer_size));
10986cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org    *buffer_size = HANDLE_EINTR(read(fd, buffer, *buffer_size));
11086cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org    if (*buffer_size == -1) {
11186cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org      perror("read");
11286cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org      ok = false;
11386cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org    }
11486cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org  }
1151a5016d36e53e2f1f7bebbcd1a7a8e4d667182d4mark@chromium.org  if (IGNORE_EINTR(close(fd)) == -1) {
11686cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org    perror("close");
11786cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org    ok = false;
11886cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org  }
11986cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org  return ok;
12086cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org}
12186cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org
12286cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.orgbool WriteFile(const char* path, const void* buffer, size_t buffer_size) {
12386cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org  int fd = HANDLE_EINTR(open(path, O_CREAT | O_TRUNC | O_WRONLY, S_IRWXU));
12486cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org  if (fd == -1) {
12586cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org    perror("open");
12686cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org    return false;
12786cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org  }
12886cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org
12986cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org  bool ok = true;
13086cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org  if (buffer) {
13186cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org    size_t bytes_written_total = 0;
13286cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org    ssize_t bytes_written_partial = 0;
13386cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org    const char* data = reinterpret_cast<const char*>(buffer);
13486cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org    while (bytes_written_total < buffer_size) {
13586cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org      bytes_written_partial =
13686cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org          HANDLE_EINTR(write(fd, data + bytes_written_total,
13786cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org                             buffer_size - bytes_written_total));
13886cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org      if (bytes_written_partial < 0) {
13986cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org        perror("write");
14086cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org        ok = false;
14186cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org        break;
14286cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org      }
14386cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org      bytes_written_total += bytes_written_partial;
14486cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org    }
14586cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org  }
1461a5016d36e53e2f1f7bebbcd1a7a8e4d667182d4mark@chromium.org  if (IGNORE_EINTR(close(fd)) == -1) {
14786cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org    perror("close");
14886cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org    ok = false;
14986cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org  }
15086cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org  return ok;
15186cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org}
15286cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org
15386cbb1e5cc967853dfc2b10f8fc8da43fc734c77benchan@chromium.org}  // namespace google_breakpad
154