From af39524b3366b8eb547f9567ae09f6a6a9e2024b Mon Sep 17 00:00:00 2001 From: Fabio Scotto di Santolo Date: Fri, 19 Sep 2025 23:33:32 +0200 Subject: [PATCH] Make a simple echo clone --- exercises/coreutils/echo/Makefile | 19 ++++++++++++ exercises/coreutils/echo/main.c | 50 +++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 exercises/coreutils/echo/Makefile create mode 100644 exercises/coreutils/echo/main.c diff --git a/exercises/coreutils/echo/Makefile b/exercises/coreutils/echo/Makefile new file mode 100644 index 0000000..873eae9 --- /dev/null +++ b/exercises/coreutils/echo/Makefile @@ -0,0 +1,19 @@ +CC := gcc +CFLAGS := -Wall -Wextra -pedantic -std=c11 -pthread -g +TARGET := echo +SRC := main.c +OBJS := $(SRC:.c=.o) + +.PHONY: all clean valgrind + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CC) $(CFLAGS) -o $@ $^ + +%.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ + +clean: + rm -f $(TARGET) $(OBJS) + diff --git a/exercises/coreutils/echo/main.c b/exercises/coreutils/echo/main.c new file mode 100644 index 0000000..ca30fee --- /dev/null +++ b/exercises/coreutils/echo/main.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + if (argc == 1) { + write(STDOUT_FILENO, "\n", 1); + return EXIT_SUCCESS; + } + + size_t argl[argc-1]; + size_t bytes_count = 0; + for (int i = 1; i < argc; i++) { + size_t len = strlen(argv[i]); + bytes_count += len; + argl[i-1] = len; + } + bytes_count += argc - 2; // whitespaces + bytes_count += 1; // newline + + char *str = malloc(bytes_count + 1); + if (str == NULL) { + perror("malloc"); + return EXIT_FAILURE; + } + + size_t pos = 0; + for (int i = 1; i < argc; i++) { + memcpy(str + pos, argv[i], argl[i-1]); + pos += argl[i-1]; + if (i < argc - 1) { + str[pos++] = ' '; + } + } + str[pos++] = '\n'; + str[pos] = '\0'; + + if (write(STDOUT_FILENO, str, pos) == -1) { + perror("write"); + free(str); + return EXIT_FAILURE; + } + + free(str); + str = NULL; + + return EXIT_SUCCESS; +}