Userspace: Add basic tee command
This commit is contained in:
parent
5a5656b2d3
commit
d3bb00cb55
|
@ -9,6 +9,7 @@ set(USERSPACE_PROJECTS
|
|||
init
|
||||
ls
|
||||
Shell
|
||||
tee
|
||||
test
|
||||
u8sum
|
||||
yes
|
||||
|
|
|
@ -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
|
||||
)
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue