blob: 019c98b00e3666e88b93036c313cba16a6139caf [file] [log] [blame]
// Copyright 2016 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "kerberos/platform_helper.h"
#include <unistd.h>
#include <algorithm>
#include <string>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/optional.h>
namespace kerberos {
namespace {
// Size limit on the total number of bytes to read from a pipe.
const size_t kMaxReadSize = 16 * 1024 * 1024; // 16 MB
// The size of the buffer used to read from a pipe.
const size_t kBufferSize = PIPE_BUF; // ~4 Kb on my system
} // namespace
base::Optional<std::string> ReadPipeToString(int fd) {
std::string data;
char buffer[kBufferSize];
size_t total_read = 0;
while (total_read < kMaxReadSize) {
const ssize_t bytes_read = HANDLE_EINTR(
read(fd, buffer, std::min(kBufferSize, kMaxReadSize - total_read)));
if (bytes_read < 0)
return base::nullopt;
if (bytes_read == 0)
return data;
total_read += bytes_read;
data.append(buffer, bytes_read);
}
// Size limit hit. Do one more read to check if the file size is exactly
// kMaxReadSize bytes.
if (HANDLE_EINTR(read(fd, buffer, 1)) != 0)
return base::nullopt;
return data;
}
base::ScopedFD WriteStringToPipe(const std::string& str) {
int pipe_fd[2];
if (!base::CreateLocalNonBlockingPipe(pipe_fd)) {
LOG(ERROR) << "Failed to create pipe";
return base::ScopedFD();
}
base::ScopedFD pipe_read_end(pipe_fd[0]);
base::ScopedFD pipe_write_end(pipe_fd[1]);
if (!base::WriteFileDescriptor(pipe_write_end.get(), str)) {
LOG(ERROR) << "Failed to write string to pipe";
return base::ScopedFD();
}
return pipe_read_end;
}
} // namespace kerberos