uint32_t read_pty_slave(fs_node_t * node, uint32_t offset, uint32_t size, uint8_t *buffer) { pty_t * pty = (pty_t *)node->device; if (pty->tios.c_lflag & ICANON) { return ring_buffer_read(pty->in, size, buffer); } else { if (pty->tios.c_cc[VMIN] == 0) { return ring_buffer_read(pty->in, MIN(size, ring_buffer_unread(pty->in)), buffer); } else { return ring_buffer_read(pty->in, MIN(pty->tios.c_cc[VMIN], size), buffer); } } }
size_t ring_buffer_read(ring_buffer_t * ring_buffer, size_t size, uint8_t * buffer) { size_t collected = 0; while (collected == 0) { spin_lock(ring_buffer->lock); while (ring_buffer_unread(ring_buffer) > 0 && collected < size) { buffer[collected] = ring_buffer->buffer[ring_buffer->read_ptr]; ring_buffer_increment_read(ring_buffer); collected++; } spin_unlock(ring_buffer->lock); wakeup_queue(ring_buffer->wait_queue_writers); if (collected == 0) { if (sleep_on(ring_buffer->wait_queue_readers) && ring_buffer->internal_stop) { ring_buffer->internal_stop = 0; break; } } } wakeup_queue(ring_buffer->wait_queue_writers); return collected; }
size_t ring_buffer_size(fs_node_t * node) { ring_buffer_t * ring_buffer = (ring_buffer_t *)node->device; return ring_buffer_unread(ring_buffer); }
int pty_available_output(fs_node_t * node) { pty_t * pty = (pty_t *)node->device; return ring_buffer_unread(pty->out); }