#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "stdinread.h"

bool
stdinread(unsigned char **buf, size_t *len, size_t *cap)
{
    *buf = malloc(*cap);
    if (*buf == NULL) {
        return false;
    }
    *len = 0;
    ssize_t n = 0;
    for (;;) {
        errno = 0;
        n = read(STDIN_FILENO, *buf + *len, *cap - *len);
        if (n == -1) {
            return false;
        }
        if (n == 0) {
            break;
        }
        *len += (size_t)n;
        if (*len == *cap) {
            unsigned char *new = realloc(*buf, *cap * 2);
            if (new == NULL) {
                free(*buf);
                *buf = NULL;
                *len = 0;
                return false;
            }
            *buf = new;
            *cap *= 2;
        }
    }
    memset(*buf + *len, 0, *cap - *len);
    return true;
}
