summaryrefslogtreecommitdiff
path: root/userland
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2024-10-09 13:59:59 +0200
committerAnton Kling <anton@kling.gg>2024-10-09 13:59:59 +0200
commitaabbd212f6ba9a38999ea6e6f478bc8afae677d0 (patch)
treecb05eab3124b5e136ec6e6425e13a6765c50b7a7 /userland
parent3743da5e714696adc9537eae8134a583f36aa1e6 (diff)
sh: Add support for running commands in the background
Diffstat (limited to 'userland')
-rw-r--r--userland/minibox/utilities/sh/ast.c5
-rw-r--r--userland/minibox/utilities/sh/ast.h1
-rw-r--r--userland/minibox/utilities/sh/lexer.c2
-rw-r--r--userland/minibox/utilities/sh/lexer.h1
-rw-r--r--userland/minibox/utilities/sh/sh.c15
5 files changed, 22 insertions, 2 deletions
diff --git a/userland/minibox/utilities/sh/ast.c b/userland/minibox/utilities/sh/ast.c
index 64dd725..98f4818 100644
--- a/userland/minibox/utilities/sh/ast.c
+++ b/userland/minibox/utilities/sh/ast.c
@@ -61,6 +61,11 @@ int parse_command(struct TOKEN **token_ptr, struct AST *cur) {
cur->file_out = token->string_rep;
token = token->next;
}
+ // Parse '&'
+ if (token && TOKEN_BACKGROUND == token->type) {
+ cur->should_background = 1;
+ token = token->next;
+ }
// Parse pipe '|'
if (token && TOKEN_PIPE == token->type) {
cur->pipe_rhs = allocate_ast();
diff --git a/userland/minibox/utilities/sh/ast.h b/userland/minibox/utilities/sh/ast.h
index ae43f67..0c5768f 100644
--- a/userland/minibox/utilities/sh/ast.h
+++ b/userland/minibox/utilities/sh/ast.h
@@ -27,6 +27,7 @@ struct AST {
struct AST *pipe_rhs; // in "func1 | func2" func2 is the piped rhs
int file_out_fd_to_use;
int file_out_append;
+ int should_background;
struct sv file_out; // in "func1 > file.txt" file.txt is the file_out
struct AST *next;
};
diff --git a/userland/minibox/utilities/sh/lexer.c b/userland/minibox/utilities/sh/lexer.c
index 0df796f..40e7211 100644
--- a/userland/minibox/utilities/sh/lexer.c
+++ b/userland/minibox/utilities/sh/lexer.c
@@ -49,7 +49,7 @@ int parse_operand(struct sv *code_ptr, struct TOKEN *cur) {
TRY_PARSE_STRING(">>", TOKEN_STREAM_APPEND);
TRY_PARSE_STRING(">", TOKEN_STREAM);
TRY_PARSE_STRING("|", TOKEN_PIPE);
- // TODO: &
+ TRY_PARSE_STRING("&", TOKEN_BACKGROUND);
// Failed to parse
return 0;
diff --git a/userland/minibox/utilities/sh/lexer.h b/userland/minibox/utilities/sh/lexer.h
index b8ca95c..887c923 100644
--- a/userland/minibox/utilities/sh/lexer.h
+++ b/userland/minibox/utilities/sh/lexer.h
@@ -11,6 +11,7 @@ typedef enum {
TOKEN_PIPE,
TOKEN_STREAM,
TOKEN_STREAM_APPEND,
+ TOKEN_BACKGROUND,
} token_type_t;
struct TOKEN {
diff --git a/userland/minibox/utilities/sh/sh.c b/userland/minibox/utilities/sh/sh.c
index 1505de3..e129044 100644
--- a/userland/minibox/utilities/sh/sh.c
+++ b/userland/minibox/utilities/sh/sh.c
@@ -7,6 +7,8 @@
#include <sys/wait.h>
#include <unistd.h>
+int active_processes = 0;
+
int execute_command(struct AST *ast, int input_fd);
int execute_binary(struct AST *ast, int input_fd) {
@@ -69,9 +71,20 @@ int execute_binary(struct AST *ast, int input_fd) {
close(out);
return execute_command(ast->pipe_rhs, slave_input);
}
+
+ active_processes++;
+ if (ast->should_background) {
+ return pid;
+ }
+
int rc;
// FIXME: Should use waitpid ... when my OS supports that
- wait(&rc);
+ for (; active_processes > 0;) {
+ if (-1 == wait(&rc)) {
+ continue;
+ }
+ active_processes--;
+ }
return rc;
}