From d3bb00cb55b38b402bb6cb0036006c4cc62e7aba Mon Sep 17 00:00:00 2001 From: Bananymous Date: Mon, 10 Jul 2023 16:07:53 +0300 Subject: [PATCH] Userspace: Add basic tee command --- userspace/CMakeLists.txt | 1 + userspace/tee/CMakeLists.txt | 16 +++++++++ userspace/tee/main.cpp | 64 ++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 userspace/tee/CMakeLists.txt create mode 100644 userspace/tee/main.cpp diff --git a/userspace/CMakeLists.txt b/userspace/CMakeLists.txt index efefef744f..d0c3bf9e80 100644 --- a/userspace/CMakeLists.txt +++ b/userspace/CMakeLists.txt @@ -9,6 +9,7 @@ set(USERSPACE_PROJECTS init ls Shell + tee test u8sum yes diff --git a/userspace/tee/CMakeLists.txt b/userspace/tee/CMakeLists.txt new file mode 100644 index 0000000000..57725e8c9e --- /dev/null +++ b/userspace/tee/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.26) + +project(tee CXX) + +set(SOURCES + main.cpp +) + +add_executable(tee ${SOURCES}) +target_compile_options(tee PUBLIC -O2 -g) +target_link_libraries(tee PUBLIC libc) + +add_custom_target(tee-install + COMMAND cp ${CMAKE_CURRENT_BINARY_DIR}/tee ${BANAN_BIN}/ + DEPENDS tee +) diff --git a/userspace/tee/main.cpp b/userspace/tee/main.cpp new file mode 100644 index 0000000000..31b15cea1d --- /dev/null +++ b/userspace/tee/main.cpp @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include + +#define MAX_FILES 20 +#define BUF_SIZE 1024 + +int main(int argc, char** argv) +{ + int files[MAX_FILES] {}; + size_t file_count = 0; + + int arg = 1; + + int oflag = O_WRONLY | O_CREAT; + if (arg < argc && strcmp(argv[arg], "-a") == 0) + { + oflag |= O_APPEND; + arg++; + } + else + { + oflag |= O_TRUNC; + } + + for (int i = arg; i < argc; i++) + { + files[file_count] = open(argv[i], oflag, 0644); + if (files[file_count] == -1) + perror(argv[i]); + else + file_count++; + + if (file_count >= MAX_FILES) + { + fprintf(stderr, "only up to %d files are supported\n", MAX_FILES); + break; + } + } + + char* buffer = (char*)malloc(BUF_SIZE); + for (;;) + { + ssize_t nread = read(STDIN_FILENO, buffer, BUF_SIZE); + if (nread == -1) + perror("stdin"); + if (nread <= 0) + break; + write(STDOUT_FILENO, buffer, nread); + for (size_t i = 0; i < file_count; i++) + write(files[i], buffer, nread); + } + free(buffer); + + if (ferror(stdin)) + perror("stdin"); + + for (size_t i = 0; i < file_count; i++) + close(files[i]); + + return 0; +}