linux-sysprog · intermediate · ~15 min
Simulate non-blocking chunked IPC drain loops with strict destination bounds checking.
Inter-process communication using anonymous pipes (pipe()) requires non-blocking drains to consume all pending data without hanging indefinitely when the pipe empties.
Implement a bounded pipe reader that reads until EOF or end-of-data:
int drain_buffer_chunks(const uint8_t *source, size_t total_available,
uint8_t *out_dest, size_t dest_cap, size_t chunk_size,
size_t *bytes_read);
source == NULL, out_dest == NULL, bytes_read == NULL, or chunk_size == 0, return -1.*bytes_read = 0.source in increments of chunk_size:remaining = total_available - *bytes_read.remaining == 0, break.to_read = min(remaining, chunk_size).*bytes_read + to_read > dest_cap, return -1 (destination capacity overflow).to_read bytes into out_dest + *bytes_read.*bytes_read += to_read.0 on success.uint8_t src[10] = "0123456789";
uint8_t dst[16]; size_t read_bytes = 0;
drain_buffer_chunks(src, 10, dst, sizeof(dst), 4, &read_bytes); // returns 0, read_bytes == 10
source: byte array; total_available: size_t; out_dest: buffer; dest_cap, chunk_size: size_t.
Returns 0 on success, -1 on capacity overflow or NULL args.
Zero heap allocations. Chunk-by-chunk copy loop.
#include <stddef.h>
#include <stdint.h>
int drain_buffer_chunks(const uint8_t *source, size_t total_available,
uint8_t *out_dest, size_t dest_cap, size_t chunk_size,
size_t *bytes_read) {
(void)source; (void)total_available; (void)out_dest; (void)dest_cap; (void)chunk_size; (void)bytes_read;
return -1;
}
Buffer overflow if dest_cap is smaller than total_available; integer underflow in remaining.
total_available == 0 returns 0 with 0 bytes read; chunk_size > total_available reads single chunk.
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.