#define _POSIX_C_SOURCE 200809L
#include <unistd.h>
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int
main(int argc, char **argv)
{
    int nflag = argc > 1 && strcmp(argv[1], "-n") == 0;
    int i;
    size_t len = 1, used = 0;
    char *buf, *p;
    for (i = 1 + nflag; i < argc; ++i) {
        size_t n = strlen(argv[i]);
        if (n >= SIZE_MAX - len) { fprintf(stderr, "echo: arguments too large\n"); return 1; }
        len += n + 1;
    }
    buf = malloc(len);
    if (buf == NULL) { perror("echo: malloc"); return 1; }
    p = buf;
    for (i = 1 + nflag; i < argc; ++i) {
        strcpy(p, argv[i]);
        p += strlen(p);
        if (i < argc - 1) *p++ = ' ';
    }
    if (!nflag) *p++ = '\n';
    len = (size_t)(p - buf);
    while (used < len) {
        ssize_t n = write(STDOUT_FILENO, buf + used, len - used);
        if (n < 0 && errno == EINTR) continue;
        if (n <= 0) { perror("echo: stdout"); free(buf); return 1; }
        used += (size_t)n;
    }
    free(buf);
    return 0;
}
