summaryrefslogtreecommitdiff
path: root/userland/sh
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2024-03-26 11:40:39 +0100
committerAnton Kling <anton@kling.gg>2024-03-26 11:40:39 +0100
commit297231bb3602d868d3891d357026c53f9fcc2402 (patch)
tree6c4f21db84912750f6f464b26bf1e4503d1fe479 /userland/sh
parent3deb2df8e62a5f0a5535ee734a5aa13b0959f53f (diff)
Increase support for signals
Diffstat (limited to 'userland/sh')
-rw-r--r--userland/sh/sh.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/userland/sh/sh.c b/userland/sh/sh.c
index 5fe7f63..e7741aa 100644
--- a/userland/sh/sh.c
+++ b/userland/sh/sh.c
@@ -2,6 +2,7 @@
#include <fcntl.h>
#include <limits.h>
#include <poll.h>
+#include <signal.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
@@ -11,6 +12,47 @@
#define IS_SPECIAL(_c) (';' == _c || '\n' == _c || '&' == _c || '|' == _c)
+struct child_process {
+ int pid;
+ struct child_process *next;
+};
+
+struct child_process *children = NULL;
+
+void add_child_process(int pid) {
+ struct child_process *new = malloc(sizeof(struct child_process));
+ new->next = NULL;
+ new->pid = pid;
+ struct child_process **entry = &children;
+ for (; *entry; entry = &(*entry)->next)
+ ;
+ *entry = new;
+}
+
+void remove_child_process(int pid) {
+ struct child_process *prev = NULL;
+ struct child_process *child = children;
+ for (; child; child = child->next) {
+ if (pid == child->pid) {
+ if (prev) {
+ prev->next = child->next;
+ } else {
+ children = child->next;
+ }
+ free(child);
+ return;
+ }
+ prev = child;
+ }
+}
+
+void slaugther_children(void) {
+ struct child_process *child = children;
+ for (; child; child = child->next) {
+ kill(child->pid, SIGTERM);
+ }
+}
+
char *PATH = "/:/bin";
int can_open(char *f) {
@@ -112,6 +154,7 @@ int execute_program(char *s, size_t l, int ignore_rc, int f_stdout,
exit(1);
}
}
+ add_child_process(pid);
close(fd[1]);
if (new_out)
@@ -213,7 +256,18 @@ char *get_line(void) {
return str;
}
+void term_handler() {
+ slaugther_children();
+ exit(0);
+}
+
int main(void) {
+ struct sigaction act = {0};
+ act.sa_handler = term_handler;
+ if (-1 == sigaction(SIGTERM, &act, NULL)) {
+ perror("sigaction");
+ return 1;
+ }
for (;;) {
printf("/ : ");
char *l = get_line();