Unix Tools

Implementations of common Unix command-line utilities written in C.


unix-tools / echo.c

echo.c raw | download
1#define _POSIX_C_SOURCE 200809L
2#include <unistd.h>
3#include <errno.h>
4#include <stdint.h>
5#include <stdio.h>
6#include <stdlib.h>
7#include <string.h>
8
9int
10main(int argc, char **argv)
11{
12 int nflag = argc > 1 && strcmp(argv[1], "-n") == 0;
13 int i;
14 size_t len = 1, used = 0;
15 char *buf, *p;
16 for (i = 1 + nflag; i < argc; ++i) {
17 size_t n = strlen(argv[i]);
18 if (n >= SIZE_MAX - len) { fprintf(stderr, "echo: arguments too large\n"); return 1; }
19 len += n + 1;
20 }
21 buf = malloc(len);
22 if (buf == NULL) { perror("echo: malloc"); return 1; }
23 p = buf;
24 for (i = 1 + nflag; i < argc; ++i) {
25 strcpy(p, argv[i]);
26 p += strlen(p);
27 if (i < argc - 1) *p++ = ' ';
28 }
29 if (!nflag) *p++ = '\n';
30 len = (size_t)(p - buf);
31 while (used < len) {
32 ssize_t n = write(STDOUT_FILENO, buf + used, len - used);
33 if (n < 0 && errno == EINTR) continue;
34 if (n <= 0) { perror("echo: stdout"); free(buf); return 1; }
35 used += (size_t)n;
36 }
37 free(buf);
38 return 0;
39}