1// Copyright 2017 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <assert.h> 6#include <string.h> 7 8#include "pty-fifo.h" 9 10static_assert((PTY_FIFO_SIZE & (PTY_FIFO_SIZE - 1)) == 0, "fifo size not power of two"); 11 12#define PTY_FIFO_MASK (PTY_FIFO_SIZE - 1) 13 14size_t pty_fifo_write(pty_fifo_t* fifo, const void* data, size_t len, bool atomic) { 15 size_t avail = PTY_FIFO_SIZE - (fifo->head - fifo->tail); 16 if (avail < len) { 17 if (atomic) { 18 return 0; 19 } 20 len = avail; 21 } 22 23 size_t offset = fifo->head & PTY_FIFO_MASK; 24 25 avail = PTY_FIFO_SIZE - offset; 26 if (len <= avail) { 27 memcpy(fifo->data + offset, data, len); 28 } else { 29 memcpy(fifo->data + offset, data, avail); 30 memcpy(fifo->data, data + avail, len - avail); 31 } 32 33 fifo->head += len; 34 return len; 35} 36 37size_t pty_fifo_read(pty_fifo_t* fifo, void* data, size_t len) { 38 size_t avail = fifo->head - fifo->tail; 39 if (avail < len) { 40 len = avail; 41 } 42 43 size_t offset = fifo->tail & PTY_FIFO_MASK; 44 45 avail = PTY_FIFO_SIZE - offset; 46 if (len <= avail) { 47 memcpy(data, fifo->data + offset, len); 48 } else { 49 memcpy(data, fifo->data + offset, avail); 50 memcpy(data + avail, fifo->data, len - avail); 51 } 52 53 fifo->tail += len; 54 return len; 55} 56 57