aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/command.h2
-rw-r--r--src/command.c66
-rw-r--r--src/hush.c7
-rw-r--r--src/lexer.c14
4 files changed, 50 insertions, 39 deletions
diff --git a/include/command.h b/include/command.h
index 3df724b..f44c103 100644
--- a/include/command.h
+++ b/include/command.h
@@ -15,10 +15,10 @@ typedef struct command {
char *infile;
char *outfile;
struct command *next;
+ struct command *prev;
pid_t pid;
int pipe[2];
- int *read_pipe;
char *args[MAX_ARGUMENT_CNT + 2];
} command;
diff --git a/src/command.c b/src/command.c
index ea198ec..20b00b1 100644
--- a/src/command.c
+++ b/src/command.c
@@ -18,12 +18,12 @@ command *create_command() {
memset(cmd->args, 0, sizeof(char*));
cmd->pipe[0] = -1;
cmd->pipe[1] = -1;
- cmd->read_pipe = NULL;
cmd->infile = NULL;
cmd->outfile = NULL;
- cmd->next = NULL;
- cmd->pid = 0;
+ cmd->pid = -1;
+ cmd->next = NULL;
+ cmd->prev= NULL;
return cmd;
}
@@ -53,7 +53,7 @@ command *commands_from_tokens(token *parsed_cmdstr, size_t *cnt) {
}
} else if (tkn->type == TKN_PIPE) {
cmd->next = create_command();
- cmd->next->read_pipe = cmd->pipe;
+ cmd->next->prev = cmd;
cmd = cmd->next;
}
@@ -69,14 +69,16 @@ void print_commands(FILE *file, command *cmds) {
for (size_t i=0; i<MAX_ARGUMENT_CNT; i++) {
fprintf(file, "%s ", cmd->args[i]);
}
- fprintf(file, "\n\tInfile: %s\n\tOutfile: %s\n\tInput Pipe: %p\n\tPid:%d\n", cmd->infile, cmd->outfile, cmd->read_pipe, cmd->pid);
- if (cmd->read_pipe) {
- fprintf(file, "\tInput Pipe: %d\n", *cmd->read_pipe);
- }
+ fprintf(file, "\n\tInfile: %s\n\tOutfile: %s\\n\tPid:%d\n", cmd->infile, cmd->outfile, cmd->pid);
+ fprintf(file, "\tRead Pipe: %d\tWrite Pipe: %d\n", cmd->pipe[0], cmd->pipe[1]);
}
}
void destroy_commands(command *cmds) {
+ if (!cmds) {
+ return;
+ }
+
command **cmd_ptr = &cmds->next;
while (*cmd_ptr) {
free(cmds);
@@ -86,47 +88,36 @@ void destroy_commands(command *cmds) {
}
pid_t execute_command(command *cmd) {
- if (cmd->next) {
- pipe(cmd->pipe);
+ if (cmd->next && pipe(cmd->pipe) == -1) {
+ perror("Failed to create pipes");
+ return -1;
}
pid_t res = fork();
if (res == 0) {
- int fdi = -1, fdo = -1;
-
- if (cmd->infile) {
- if (!freopen(cmd->infile, "r", stdin)) {
- perror("Could not open input file");
+ if (cmd->infile && !freopen(cmd->infile, "r", stdin)) {
+ perror("Could not open input file");
+ exit(EXIT_FAILURE);
+ } else if (cmd->prev) {
+ close(cmd->prev->pipe[1]);
+ if (dup2(cmd->prev->pipe[0], STDIN_FILENO) == -1) {
+ perror("Could not assign pipe to stdin");
exit(EXIT_FAILURE);
}
- } else if (cmd->read_pipe && *cmd->read_pipe >= 0) {
- fdi = dup2(*(cmd->read_pipe), STDIN_FILENO);
- close(*(cmd->read_pipe));
+ close(cmd->prev->pipe[0]);
}
- if (cmd->outfile) {
- if (!freopen(cmd->outfile, "w", stdout)) {
+ if (cmd->outfile && !freopen(cmd->outfile, "w", stdout)) {
perror("Could not open output file");
exit(EXIT_FAILURE);
- }
} else if (cmd->next) {
- fdo = dup2(cmd->pipe[1], STDOUT_FILENO);
- }
-
- fprintf(stderr, "In command:\n");
- fprintf(stderr, "STDIN: %d\tSTDOUT: %d\n", fdi, fdo);
-
-
- if (cmd->pipe[0] >= 0) {
close(cmd->pipe[0]);
- cmd->pipe[0] = -1;
- }
-
- if (cmd->pipe[1] >= 0) {
+ if (dup2(cmd->pipe[1], STDOUT_FILENO) == -1) {
+ perror("Could not assign pipe to stdout");
+ exit(EXIT_FAILURE);
+ }
close(cmd->pipe[1]);
- cmd->pipe[1] = -1;
}
-
execvp(cmd->command, cmd->args);
perror("Could not run command");
@@ -136,6 +127,11 @@ pid_t execute_command(command *cmd) {
return -1;
}
+ if (cmd->prev) {
+ close(cmd->prev->pipe[0]);
+ close(cmd->prev->pipe[1]);
+ }
+
cmd->pid = res;
return res;
}
diff --git a/src/hush.c b/src/hush.c
index 255a058..557ae1e 100644
--- a/src/hush.c
+++ b/src/hush.c
@@ -87,7 +87,7 @@ int main(int argc, char **argv) {
}
}
- print_commands(stdout, cmds);
+ // print_commands(stdout, cmds);
for (command *cmd = cmds; cmd; cmd = cmd->next) {
if (cmd->pid > 0) {
@@ -97,12 +97,13 @@ int main(int argc, char **argv) {
}
}
- free_tokens:
- destroy_tokens(parsed_cmd);
free_commands:
destroy_commands(cmds);
+ free_tokens:
+ destroy_tokens(parsed_cmd);
+
draw_prompt:
fprintf(stdout, "$ ");
}
diff --git a/src/lexer.c b/src/lexer.c
index a6af008..38ae558 100644
--- a/src/lexer.c
+++ b/src/lexer.c
@@ -153,6 +153,7 @@ token *validate_command(token *cmd) {
bool infile_defined = false;
bool outfile_defined = false;
bool looking_for_file = false;
+ bool reads_from_pipe = false;
for (token *tkn = cmd; tkn; tkn = tkn->next) {
if (!prev) {
@@ -183,6 +184,15 @@ token *validate_command(token *cmd) {
}
arg_cnt = 0;
+ reads_from_pipe = true;
+
+ if (infile_defined) {
+ return tkn;
+ }
+
+ infile_defined = false;
+ outfile_defined = false;
+
} else if (tkn->type == TKN_IN_REDIR || tkn->type == TKN_OUT_REDIR) {
if (prev->type == TKN_PIPE || prev->type == TKN_IN_REDIR ||
prev->type == TKN_OUT_REDIR) {
@@ -196,6 +206,10 @@ token *validate_command(token *cmd) {
if (prev->type != TKN_VARKEY) {
return tkn;
}
+ } else if (tkn->type == TKN_PIPE) {
+ if (outfile_defined) {
+ return tkn;
+ }
}
if (looking_for_file &&