mirror of
https://github.com/BoredDevNL/BoredOS.git
synced 2026-05-15 10:48:38 +00:00
Piping of commands into text files
usage: xxx(command) > xxxx.xxx (file)
This commit is contained in:
parent
5e3dc237cc
commit
e7752b7253
13 changed files with 134 additions and 41 deletions
BIN
brewos.iso
BIN
brewos.iso
Binary file not shown.
BIN
build/brewos.elf
BIN
build/brewos.elf
Binary file not shown.
Binary file not shown.
BIN
build/cmd.o
BIN
build/cmd.o
Binary file not shown.
BIN
build/explorer.o
BIN
build/explorer.o
Binary file not shown.
Binary file not shown.
BIN
build/notepad.o
BIN
build/notepad.o
Binary file not shown.
Binary file not shown.
|
|
@ -27,6 +27,7 @@ void cli_cmd_mkdir(char *args);
|
||||||
void cli_cmd_rm(char *args);
|
void cli_cmd_rm(char *args);
|
||||||
void cli_cmd_echo(char *args);
|
void cli_cmd_echo(char *args);
|
||||||
void cli_cmd_cat(char *args);
|
void cli_cmd_cat(char *args);
|
||||||
|
void cli_cmd_touch(char *args);
|
||||||
|
|
||||||
// Memory management commands
|
// Memory management commands
|
||||||
void cli_cmd_meminfo(char *args);
|
void cli_cmd_meminfo(char *args);
|
||||||
|
|
|
||||||
|
|
@ -239,3 +239,39 @@ void cli_cmd_cat(char *args) {
|
||||||
|
|
||||||
fat32_close(fh);
|
fat32_close(fh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cli_cmd_touch(char *args) {
|
||||||
|
if (!args || args[0] == 0) {
|
||||||
|
cli_write("Usage: touch <filename>\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char filename[256];
|
||||||
|
int i = 0;
|
||||||
|
while (args[i] && args[i] != ' ' && args[i] != '\t') {
|
||||||
|
filename[i] = args[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
filename[i] = 0;
|
||||||
|
|
||||||
|
// Check if file already exists
|
||||||
|
if (fat32_exists(filename)) {
|
||||||
|
cli_write("File already exists: ");
|
||||||
|
cli_write(filename);
|
||||||
|
cli_write("\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open file in write mode to create it
|
||||||
|
FAT32_FileHandle *fh = fat32_open(filename, "w");
|
||||||
|
if (!fh) {
|
||||||
|
cli_write("Error: Cannot create file\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fat32_close(fh);
|
||||||
|
|
||||||
|
cli_write("Created: ");
|
||||||
|
cli_write(filename);
|
||||||
|
cli_write("\n");
|
||||||
|
}
|
||||||
|
|
|
||||||
111
src/kernel/cmd.c
111
src/kernel/cmd.c
|
|
@ -14,8 +14,8 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#define CMD_COLS 70
|
#define CMD_COLS 116
|
||||||
#define CMD_ROWS 25
|
#define CMD_ROWS 41
|
||||||
#define LINE_HEIGHT 10
|
#define LINE_HEIGHT 10
|
||||||
#define CHAR_WIDTH 8
|
#define CHAR_WIDTH 8
|
||||||
#define PROMPT "> "
|
#define PROMPT "> "
|
||||||
|
|
@ -108,6 +108,10 @@ static int pager_top_line = 0;
|
||||||
|
|
||||||
// Boot time for uptime
|
// Boot time for uptime
|
||||||
int boot_time_init = 0;
|
int boot_time_init = 0;
|
||||||
|
|
||||||
|
// Output redirection state
|
||||||
|
static FAT32_FileHandle *redirect_file = NULL;
|
||||||
|
static char redirect_mode = 0; // '>' for write, 'a' for append, 0 for normal output
|
||||||
int boot_year, boot_month, boot_day, boot_hour, boot_min, boot_sec;
|
int boot_year, boot_month, boot_day, boot_hour, boot_min, boot_sec;
|
||||||
|
|
||||||
// --- Helpers ---
|
// --- Helpers ---
|
||||||
|
|
@ -193,6 +197,12 @@ static void cmd_scroll_up() {
|
||||||
|
|
||||||
// Public for CLI apps to use
|
// Public for CLI apps to use
|
||||||
void cmd_putchar(char c) {
|
void cmd_putchar(char c) {
|
||||||
|
// If output is being redirected to a file, write there instead
|
||||||
|
if (redirect_file && redirect_mode) {
|
||||||
|
fat32_write(redirect_file, &c, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
cursor_col = 0;
|
cursor_col = 0;
|
||||||
cursor_row++;
|
cursor_row++;
|
||||||
|
|
@ -225,8 +235,14 @@ void cmd_putchar(char c) {
|
||||||
|
|
||||||
// Public for CLI apps to use
|
// Public for CLI apps to use
|
||||||
void cmd_write(const char *str) {
|
void cmd_write(const char *str) {
|
||||||
while (*str) {
|
// If output is being redirected to a file, write there instead
|
||||||
cmd_putchar(*str++);
|
if (redirect_file && redirect_mode) {
|
||||||
|
fat32_write(redirect_file, (void *)str, cmd_strlen(str));
|
||||||
|
} else {
|
||||||
|
// Normal output to screen
|
||||||
|
while (*str) {
|
||||||
|
cmd_putchar(*str++);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -371,6 +387,8 @@ static const CommandEntry commands[] = {
|
||||||
{"echo", cli_cmd_echo},
|
{"echo", cli_cmd_echo},
|
||||||
{"CAT", cli_cmd_cat},
|
{"CAT", cli_cmd_cat},
|
||||||
{"cat", cli_cmd_cat},
|
{"cat", cli_cmd_cat},
|
||||||
|
{"TOUCH", cli_cmd_touch},
|
||||||
|
{"touch", cli_cmd_touch},
|
||||||
// Memory Management Commands
|
// Memory Management Commands
|
||||||
{"MEMINFO", cli_cmd_meminfo},
|
{"MEMINFO", cli_cmd_meminfo},
|
||||||
{"meminfo", cli_cmd_meminfo},
|
{"meminfo", cli_cmd_meminfo},
|
||||||
|
|
@ -390,7 +408,7 @@ static const CommandEntry commands[] = {
|
||||||
// --- Dispatcher ---
|
// --- Dispatcher ---
|
||||||
|
|
||||||
// Buffer for capturing command output
|
// Buffer for capturing command output
|
||||||
static char pipe_buffer[4096];
|
static char pipe_buffer[8192];
|
||||||
static int pipe_buffer_pos = 0;
|
static int pipe_buffer_pos = 0;
|
||||||
|
|
||||||
static void pipe_capture_write(const char *str) {
|
static void pipe_capture_write(const char *str) {
|
||||||
|
|
@ -425,42 +443,73 @@ static void cmd_exec_single(char *cmd) {
|
||||||
cmd_write("\n");
|
cmd_write("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute command with pipe support
|
// Execute command with redirection and pipe support
|
||||||
static void cmd_exec(char *cmd) {
|
static void cmd_exec(char *cmd) {
|
||||||
// Check for pipe operator
|
// Check for redirection operators (> or >>)
|
||||||
char *pipe_ptr = NULL;
|
char *redirect_ptr = NULL;
|
||||||
|
char redirect_op = 0; // '>' or 'a' for append
|
||||||
|
char output_file[256] = {0};
|
||||||
|
int cmd_len = 0;
|
||||||
|
|
||||||
for (int i = 0; cmd[i]; i++) {
|
for (int i = 0; cmd[i]; i++) {
|
||||||
if (cmd[i] == '|' && (i == 0 || cmd[i-1] != '>' && cmd[i+1] != '>' )) {
|
if (cmd[i] == '>' && cmd[i+1] == '>') {
|
||||||
pipe_ptr = &cmd[i];
|
redirect_ptr = cmd + i + 2;
|
||||||
|
redirect_op = 'a'; // append
|
||||||
|
cmd_len = i;
|
||||||
|
break;
|
||||||
|
} else if (cmd[i] == '>') {
|
||||||
|
redirect_ptr = cmd + i + 1;
|
||||||
|
redirect_op = '>'; // write
|
||||||
|
cmd_len = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pipe_ptr) {
|
// If redirection found, set it up
|
||||||
// No pipe - execute normally
|
if (redirect_ptr) {
|
||||||
cmd_exec_single(cmd);
|
// Null terminate command
|
||||||
return;
|
cmd[cmd_len] = 0;
|
||||||
}
|
|
||||||
|
// Parse output filename
|
||||||
// Split into two commands
|
int i = 0;
|
||||||
*pipe_ptr = 0;
|
while (redirect_ptr[i] && (redirect_ptr[i] == ' ' || redirect_ptr[i] == '\t')) {
|
||||||
char *second_cmd = pipe_ptr + 1;
|
i++;
|
||||||
|
}
|
||||||
// Execute first command with output captured
|
|
||||||
pipe_buffer_pos = 0;
|
int j = 0;
|
||||||
cmd_memset(pipe_buffer, 0, sizeof(pipe_buffer));
|
while (redirect_ptr[i] && redirect_ptr[i] != ' ' && redirect_ptr[i] != '\t') {
|
||||||
|
output_file[j++] = redirect_ptr[i++];
|
||||||
FAT32_FileHandle *pipe_file = fat32_open("_pipe_temp.tmp", "w");
|
}
|
||||||
if (!pipe_file) {
|
output_file[j] = 0;
|
||||||
cmd_write("Error: Cannot create pipe\n");
|
|
||||||
return;
|
if (!output_file[0]) {
|
||||||
|
cmd_write("Error: No output file specified\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open file for redirection
|
||||||
|
const char *mode = (redirect_op == 'a') ? "a" : "w";
|
||||||
|
redirect_file = fat32_open(output_file, mode);
|
||||||
|
if (!redirect_file) {
|
||||||
|
cmd_write("Error: Cannot open file for redirection\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
redirect_mode = redirect_op;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Execute the command
|
||||||
cmd_exec_single(cmd);
|
cmd_exec_single(cmd);
|
||||||
|
|
||||||
fat32_close(pipe_file);
|
// Close redirected file if it was opened
|
||||||
|
if (redirect_file) {
|
||||||
cmd_exec_single(second_cmd);
|
fat32_close(redirect_file);
|
||||||
|
redirect_file = NULL;
|
||||||
|
redirect_mode = 0;
|
||||||
|
cmd_write("Output redirected to: ");
|
||||||
|
cmd_write(output_file);
|
||||||
|
cmd_write("\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -335,21 +335,28 @@ static void explorer_paint(Window *win) {
|
||||||
// Draw icon (larger area)
|
// Draw icon (larger area)
|
||||||
explorer_draw_file_icon(item_x + 5, item_y + 5, items[i].is_directory);
|
explorer_draw_file_icon(item_x + 5, item_y + 5, items[i].is_directory);
|
||||||
|
|
||||||
// Draw name below icon
|
// Draw name below icon with text wrapping
|
||||||
uint32_t text_color = (i == selected_item) ? COLOR_WHITE : COLOR_BLACK;
|
uint32_t text_color = (i == selected_item) ? COLOR_WHITE : COLOR_BLACK;
|
||||||
int name_len = explorer_strlen(items[i].name);
|
int name_len = explorer_strlen(items[i].name);
|
||||||
int text_x = item_x + 5;
|
int text_x = item_x + 5;
|
||||||
int text_y = item_y + 50;
|
int text_y = item_y + 50;
|
||||||
|
int max_name_width = EXPLORER_ITEM_WIDTH - 10; // 110 pixels available for text
|
||||||
|
int chars_per_line = max_name_width / 8; // 8 pixels per character
|
||||||
|
|
||||||
// Truncate name if too long
|
// Draw wrapped filename
|
||||||
char display_name[24];
|
int line_offset = 0;
|
||||||
int copy_len = name_len > 18 ? 18 : name_len;
|
char line_buffer[25];
|
||||||
for (int j = 0; j < copy_len; j++) {
|
for (int j = 0; j < name_len; j++) {
|
||||||
display_name[j] = items[i].name[j];
|
int pos_in_line = j % chars_per_line;
|
||||||
|
line_buffer[pos_in_line] = items[i].name[j];
|
||||||
|
line_buffer[pos_in_line + 1] = 0;
|
||||||
|
|
||||||
|
// Draw line when we reach end of line or end of name
|
||||||
|
if (pos_in_line == chars_per_line - 1 || j == name_len - 1) {
|
||||||
|
draw_string(text_x, text_y + (line_offset * 10), line_buffer, text_color);
|
||||||
|
line_offset++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
display_name[copy_len] = 0;
|
|
||||||
|
|
||||||
draw_string(text_x, text_y, display_name, text_color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw dialogs
|
// Draw dialogs
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ static void minesweeper_paint(Window *win) {
|
||||||
} else if (game_won) {
|
} else if (game_won) {
|
||||||
draw_string(win->x + 10, win->y + 30, "You Won!", COLOR_BLUE);
|
draw_string(win->x + 10, win->y + 30, "You Won!", COLOR_BLUE);
|
||||||
} else {
|
} else {
|
||||||
draw_string(win->x + 10, win->y + 30, "Minesweeper", COLOR_BLACK);
|
draw_string(win->x + 10, win->y + 30, "", COLOR_BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw grid
|
// Draw grid
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue