feat: implemented pipes and redirects + background operator

This commit is contained in:
2024-03-16 23:07:19 +01:00
parent 6b9bedac3c
commit 7e6c1147db
10 changed files with 246 additions and 74 deletions

55
main.c
View File

@@ -1,4 +1,3 @@
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
@@ -12,11 +11,15 @@
#include "cmd.h"
// general TODO:
// * properly bind stdin/stdout for piped commands
// * run chains in bg if given '&'
// * manage < and > redirects
// * signal handling
// * builtins - 'kill'
// * simple command history
// * run scripts with argv[]
// * redirect stderr with the n> operator
// * allow multiple redirects (turn chain.in and chain.out into char**)
//
// Big rewrite: create a 'shell' struct which is the actual program to run
// this struct would take care of things like command history, signal handling, etc
/**
* This function skips one COMMAND, including redirects and pipes (if any).
@@ -44,7 +47,7 @@ void skipCommand(List *lp) {
}
/**
* This function checks whether the current COMPOSITION operator passes (and thus should execute the next function).
* This function checks whether the current COMPOSITION operator passes (and thus should execute the next command).
* @param s the COMPOSITION operator.
* @param status the exit status of the last ran command.
* @return whether the COMPOSITION succeeds/whether to execute the next command.
@@ -57,17 +60,48 @@ bool compositionPasses(char *s, int status) {
return false;
}
#if EXT_PROMPT
int execute_script(char* script) {
FILE* file = fopen(script, "r");
if (file == NULL) {
printf("Error: provided Scriptfile, '%s', does not exist or is inaccessible!\n", script);
return 1;
}
char line[512];
while (fgets(line, sizeof(line), file)) {
printf("%s", line);
//TODO: continue working here on the script functionality later, after the Refactor
}
fclose(file);
return 0;
}
#endif
/**
* Driver function. Contains the main loop which collects and parses input, and decides what and how to execute + output.
*/
int main(int argc, char *argv[]) {
#if EXT_PROMPT
if (argc >= 2) {
if (argc > 2) {
printf("Error: unexpected number of arguments!\n");
return 0;
} else {
if (execute_script(argv[1])) return 1;
}
}
#endif
char *inputLine;
List tokenList;
int status = 0;
bool do_loop = true;
#if EXT_PROMPT
bool debug = false;
char cwd[101], *usr;
char cwd[128], *usr, prompt[256];
#endif
// Disable buffering so we don't have to deal with out-of-order prints.
@@ -80,10 +114,13 @@ int main(int argc, char *argv[]) {
#if EXT_PROMPT
getcwd(cwd, sizeof(cwd));
usr = getlogin();
if (!status) printf("\x1b[33m%s \x1b[36m%s \x1b[32m>\x1b[0m ", usr, cwd);
if ( status) printf("\x1b[33m%s \x1b[36m%s \x1b[31m>\x1b[0m ", usr, cwd);
if (!status) snprintf(prompt, 200*sizeof(char), "\x1b[33m%s \x1b[36m%s \x1b[32m>\x1b[0m ", usr, cwd);
if ( status) snprintf(prompt, 200*sizeof(char), "\x1b[33m%s \x1b[36m%s \x1b[31m>\x1b[0m ", usr, cwd);
inputLine = readInputLine(prompt);
#else
inputLine = readInputLine();
#endif
inputLine = readInputLine();
// We have modified the readInputLine function to return NULL on EOF.
if (inputLine == NULL) {
do_loop = false;