echo.c (1350B)
- // Collection of Unix tools, comparable to coreutils
- // SPDX-FileCopyrightText: 2017-2023 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
- // SPDX-License-Identifier: MPL-2.0
- #define _POSIX_C_SOURCE 200809L
- #include <stdbool.h> /* bool */
- #include <stdio.h> /* perror */
- #include <stdlib.h> /* malloc */
- #include <string.h> /* strlen */
- #include <unistd.h> /* write */
- int
- main(int argc, char *argv[])
- {
- size_t arg_len = 0;
- char *buffer, *buffer_p;
- int err = 0;
- bool opt_n = false;
- if((argc >= 2) && (strncmp(argv[1], "-n", 3) == 0))
- {
- opt_n = true;
- argc--;
- argv++;
- }
- for(int i = 1; i < argc; i++)
- {
- arg_len += strlen(argv[i]) + 1; // str + space|newline
- }
- if(arg_len == 0)
- {
- if(opt_n) return 0;
- if(write(1, "\n", 1) < 1)
- {
- perror("echo: write(1, \"\n\", 1)");
- return 1;
- }
- return 0;
- }
- if(opt_n) arg_len--; // no newline
- buffer = malloc(arg_len);
- if(buffer == NULL)
- {
- perror("echo: malloc(arg_len)");
- return 1;
- }
- buffer_p = buffer;
- for(int i = 1; i < argc; i++)
- {
- size_t len = strlen(argv[i]);
- memcpy(buffer_p, argv[i], len);
- buffer_p += len;
- if(i < argc - 1)
- {
- *buffer_p++ = ' ';
- }
- }
- if(!opt_n) *buffer_p++ = '\n';
- if(write(1, buffer, arg_len) < (ssize_t)arg_len)
- {
- perror("echo: write(1, buffer, arg_len)");
- err++;
- }
- free(buffer);
- return err;
- }