linux-sysprog · intermediate · ~15 min

Non-Blocking Pipe Drainer

Simulate non-blocking chunked IPC drain loops with strict destination bounds checking.

Challenge

Inter-process communication using anonymous pipes (pipe()) requires non-blocking drains to consume all pending data without hanging indefinitely when the pipe empties.

Your Task

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);

Rules

  1. If source == NULL, out_dest == NULL, bytes_read == NULL, or chunk_size == 0, return -1.
  2. Initialize *bytes_read = 0.
  3. Read from source in increments of chunk_size:
    • Let remaining = total_available - *bytes_read.
    • If remaining == 0, break.
    • Determine to_read = min(remaining, chunk_size).
    • If *bytes_read + to_read > dest_cap, return -1 (destination capacity overflow).
    • Copy to_read bytes into out_dest + *bytes_read.
    • Increment *bytes_read += to_read.
  4. Return 0 on success.

Example

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

Input format

source: byte array; total_available: size_t; out_dest: buffer; dest_cap, chunk_size: size_t.

Output format

Returns 0 on success, -1 on capacity overflow or NULL args.

Constraints

Zero heap allocations. Chunk-by-chunk copy loop.

Starter code

#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;
}

Common mistakes

Buffer overflow if dest_cap is smaller than total_available; integer underflow in remaining.

Edge cases to handle

total_available == 0 returns 0 with 0 bytes read; chunk_size > total_available reads single chunk.

Background lessons

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.