Userspace: Add basic tee command

This commit is contained in:
Bananymous 2023-07-10 16:07:53 +03:00
parent 5a5656b2d3
commit d3bb00cb55
3 changed files with 81 additions and 0 deletions

View File

@ -9,6 +9,7 @@ set(USERSPACE_PROJECTS
init
ls
Shell
tee
test
u8sum
yes

View File

@ -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
)

64
userspace/tee/main.cpp Normal file
View File

@ -0,0 +1,64 @@
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#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;
}