| // Copyright 2016 The Fuchsia 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 "util.h" |
| |
| #include <errno.h> |
| #include <fcntl.h> |
| #include <stdlib.h> |
| #include <strings.h> |
| #include <unistd.h> |
| |
| #include <unittest/unittest.h> |
| |
| // readable: is the pipe readable on the child side? |
| // returns [our_fd, child_fd] |
| int stdio_pipe(int pipe_fds[2], bool readable) { |
| int r; |
| if ((r = pipe(pipe_fds)) != 0) { // Initially gives [reader, writer] |
| return r; |
| } |
| |
| if (readable) { |
| // If child is to be readable, we want |
| // [our_fd: writer, child_fd: reader], so we must swap |
| int tmp = pipe_fds[0]; |
| pipe_fds[0] = pipe_fds[1]; |
| pipe_fds[1] = tmp; |
| } |
| |
| return 0; |
| } |
| |
| int read_to_end(int fd, uint8_t** buf, size_t* buf_size) { |
| size_t start_len = *buf_size; |
| size_t unused = 16; |
| |
| *buf_size += unused; |
| *buf = realloc(*buf, *buf_size); |
| |
| while (1) { |
| if (unused == 0) { |
| // Double the buffer size |
| unused = *buf_size; |
| *buf_size += unused; |
| *buf = realloc(*buf, *buf_size); |
| } |
| |
| uint8_t* buf_slice = &(*buf)[*buf_size-unused]; |
| int result = read(fd, buf_slice, unused); |
| if (result == 0) { |
| *buf_size -= unused; |
| return *buf_size - start_len; |
| } else if (result > 0) { |
| unused -= result; |
| } else if (result == EINTR) { |
| } else { |
| *buf_size -= unused; |
| return result; |
| } |
| } |
| } |