diff options
author | Anton Kling <anton@kling.gg> | 2024-10-09 13:59:59 +0200 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2024-10-09 13:59:59 +0200 |
commit | aabbd212f6ba9a38999ea6e6f478bc8afae677d0 (patch) | |
tree | cb05eab3124b5e136ec6e6425e13a6765c50b7a7 /userland | |
parent | 3743da5e714696adc9537eae8134a583f36aa1e6 (diff) |
sh: Add support for running commands in the background
Diffstat (limited to 'userland')
-rw-r--r-- | userland/minibox/utilities/sh/ast.c | 5 | ||||
-rw-r--r-- | userland/minibox/utilities/sh/ast.h | 1 | ||||
-rw-r--r-- | userland/minibox/utilities/sh/lexer.c | 2 | ||||
-rw-r--r-- | userland/minibox/utilities/sh/lexer.h | 1 | ||||
-rw-r--r-- | userland/minibox/utilities/sh/sh.c | 15 |
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; } |