summaryrefslogtreecommitdiffstats
path: root/02_exercise/shell.c
diff options
context:
space:
mode:
Diffstat (limited to '02_exercise/shell.c')
-rw-r--r--02_exercise/shell.c49
1 files changed, 26 insertions, 23 deletions
diff --git a/02_exercise/shell.c b/02_exercise/shell.c
index fc50995..03ff6b3 100644
--- a/02_exercise/shell.c
+++ b/02_exercise/shell.c
@@ -11,15 +11,14 @@
#include "prompt_utils.h"
#include "builtins.h"
+process *processes;
-process *processes ;
-
-void signal_handeler (int signal) {
+void signal_handler(int signal) {
printf("Received signal %d", signal);
- if(signal == SIGINT) {
- for(size_t i = 0; i < arrayLen(processes); ++i) {
+ if (signal == SIGINT) {
+ for (size_t i = 0; i < arrayLen(processes); ++i) {
pid_t pid = processes[i].pid;
- if(pid != 0) {
+ if (pid != 0) {
kill(pid, SIGINT);
}
}
@@ -29,8 +28,9 @@ void signal_handeler (int signal) {
int main(void) {
setvbuf(stderr, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
+
// I don't think the shell should exit on SIG_TERM
- if(signal(SIGINT, SIG_IGN)== SIG_ERR) {
+ if (signal(SIGINT, SIG_IGN) == SIG_ERR) {
perror("Couldn't ignore sigterm");
exit(errno);
}
@@ -38,19 +38,19 @@ int main(void) {
printf("Welcome! Available built-ins are:\n"
"cd: `cd <path>` - if no path is given, return to the current dir\n"
"wait: `wait pid1 ... pidN` - wait on the processes and report their exit conditions\n"
- "fg: `fg pid` - pulls a process from the background back in the foreground (#TODO)\n"
+ "fg: `fg pid` - pulls a process from the background back in the foreground\n"
"\n"
- "You can put processes in the background using the unary `&` for new processes, and using CTRL-Z (#TODO) for already running ones\n"
- "With `|` you can pipe the output from one process to the input of another\n"
+ "You can put processes in the background using `&`\n"
+ "And with `|` you can pipe the output from one process to the input of another\n"
);
char const *const original_wd = get_current_dir_name();
char const *prompt = relative_path(original_wd, original_wd);
bool done = false;
while (!done) {
- char *line = NULL;
- size_t cap = 0;
- __ssize_t length = 0;
+ char *line = NULL;
+ size_t cap = 0;
+ __ssize_t length;
printf("%s > ", prompt);
if ((length = getline(&line, &cap, stdin)) < 0) {
@@ -73,7 +73,7 @@ int main(void) {
perror("Can't chain cd with other processes");
}
int ret;
- switch(arrayLen(processes[0].argv)) {
+ switch (arrayLen(processes[0].argv)) {
case 3:
ret = chdir(processes[0].argv[1]);
break;
@@ -89,17 +89,20 @@ int main(void) {
if (ret)
printf("[%i] ", ret);
- free((void *)prompt);
+ free((void *) prompt);
char const *current_wd = get_current_dir_name();
prompt = relative_path(original_wd, current_wd);
- free((void *)current_wd);
+ free((void *) current_wd);
} else if (strcmp(processes[0].argv[0], "exit") == 0) {
done = true;
} else if (strcmp(processes[0].argv[0], "wait") == 0) {
- builtin_wait(processes[0]);
+ builtin_wait(processes[0], false);
+ } else if (strcmp(processes[0].argv[0], "fg") == 0) {
+ // same behaviour as wait, just bind to shell again (i.e. terminate process on ctrl-c)
+ builtin_wait(processes[0], true);
} else {
- if(arrayLen(processes) != 0 && processes[0].blocking) {
- signal(SIGINT, signal_handeler);
+ if (arrayLen(processes) != 0 && processes[arrayLen(processes) - 1].blocking) {
+ signal(SIGINT, signal_handler);
}
for (size_t i = 0; i < arrayLen(processes); ++i) {
int ret = exec_command(processes[i]);
@@ -109,12 +112,12 @@ int main(void) {
signal(SIGINT, SIG_IGN);
}
- free((void *)line);
+ free((void *) line);
line = NULL;
- cap = 0;
+ cap = 0;
free_processes(&processes);
}
- free((void *)original_wd);
- free((void *)prompt);
+ free((void *) original_wd);
+ free((void *) prompt);
}