| // 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/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.data(), |
| str.size())) { |
| LOG(ERROR) << "Failed to write string to pipe"; |
| return base::ScopedFD(); |
| } |
| return pipe_read_end; |
| } |
| |
| } // namespace kerberos |