From c9f0ec1bda7b53f7bea01e8e02c9b9b1e843ce38 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 22 Nov 2023 21:36:45 +0300 Subject: [PATCH] rc --- TODO | 2 +- builder/builder.c | 4 +- config.h | 6 ++ libmu/unused.h | 2 +- shell/rc.c | 141 +++++++++++++++++++++++++++++++++++++++++++++- sysutils/mount.c | 18 ++++++ 6 files changed, 168 insertions(+), 5 deletions(-) create mode 100644 sysutils/mount.c diff --git a/TODO b/TODO index f9c7d30..ba44dd9 100644 --- a/TODO +++ b/TODO @@ -62,7 +62,7 @@ Findutils: xargs Shell: - rc - run command + rc - run command (pipe, ~ | <> <<>> & " parsing) Init: sinit - Simple init diff --git a/builder/builder.c b/builder/builder.c index ed1bd1c..cf4195e 100644 --- a/builder/builder.c +++ b/builder/builder.c @@ -19,7 +19,7 @@ void remove_suffix(char *base, const char *suffix) { char *MakePath(const char *src, const char *output_dir) { char *dup = strdup(src); if (dup == NULL) { - fprintf(stderr, "builder: strdup failed"); + fprintf(stderr, "builder: strdup failed\n"); exit(1); } @@ -51,7 +51,7 @@ void Compile(const char *src, const char *output_dir) { } else if (pid == -1) { - fprintf(stderr, "builder: fork failed"); + fprintf(stderr, "builder: fork failed\n"); exit(1); } diff --git a/config.h b/config.h index 62de33d..5b1760e 100644 --- a/config.h +++ b/config.h @@ -13,6 +13,12 @@ /* block size (du)*/ #define BLK_SIZE 512 +/* mount config */ +#define MOUNT_CFG "/etc/fstab" + +/* RunComm prompt */ +#define RC_PS "> " + /* Options: To disable, comment line */ /* Add escape-char support in echo */ #define ECHO_FANCY diff --git a/libmu/unused.h b/libmu/unused.h index b31a8e3..09dfc9c 100644 --- a/libmu/unused.h +++ b/libmu/unused.h @@ -1,6 +1,6 @@ #ifndef _UNUSED_H #define _UNUSED_H -#define UNUSED(p) (void)p +#define UNUSED(p) ((void)p) #endif diff --git a/shell/rc.c b/shell/rc.c index 061ed7e..ce4afeb 100644 --- a/shell/rc.c +++ b/shell/rc.c @@ -1,3 +1,142 @@ -int main(void) { +#include +#include +#include +#include +#include +#include +#include +#include "config.h" +#include "unused.h" + +#define TOK_DELIM " \t\r\n\a" +unsigned int exit_flag; + +int rc_cd(char **args, char **envp); +int rc_exit(char **args, char **envp); + +/* Builtin commands */ +char *cmd[] = {"cd", "exit", "which"}; +int (*func[])(char **args, char **envp) = {rc_cd, rc_exit}; + +int rc_exit(char **args, char **envp) { + UNUSED(args); + UNUSED(envp); + exit_flag = 1; + return 0; +} + +int rc_cd(char **args, char **envp) { + UNUSED(envp); + + int status = 0; + if (args[0] == NULL) + status = chdir(getenv("HOME")); + + else + status = chdir(args[0]); + + if (status < 0) { + fprintf(stderr, "rc: cd: Not such directory\n"); + return 1; + } + + return 0; +} + +/* Shell */ +int execute(char **tok, char **envp) { + if (tok[0] == NULL) + return 0; + + for (size_t i = 0; i < sizeof(cmd) / sizeof(char *); i++) + if (!strcmp(tok[0], cmd[i])) + return func[i](tok + 1, envp); + + /* TODO: pipe */ + /* If its not builtin cmd */ + pid_t pid; + if ((pid = fork()) == 0) { + if (pid == 1) + exit(1); + + execvp(tok[0], tok); + exit(1); + } + + if (pid == -1) { + fprintf(stderr, "rc: fork failed\n"); + return 1; + } + + int status = 0; + waitpid(pid, &status, 0); + return status; +} + +char **tokenize(char *str) { + size_t buflen = 0; + + char *p = str; + while (*p++) + if (*p == ' ') + buflen++; + + char **tokens = malloc(sizeof(char *) * buflen); + if (tokens == NULL) { + fprintf(stderr, "rc: malloc failed\n"); + exit(1); + } + + char *token = strtok(str, TOK_DELIM); + + int i = 0; + while (token != NULL) { + tokens[i] = token; + token = strtok(NULL, TOK_DELIM); + i++; + } + + tokens[i] = NULL; + return tokens; +} + +char *readline(FILE *fp, char *prompt) { + printf("%s", prompt); + + char *str = NULL; + size_t len = 0; + if (getline(&str, &len, fp) == -1) + return NULL; + + return str; +} + +int main(int argc, char **argv, char **envp) { + UNUSED(argc); + UNUSED(argv); + + char *prompt = RC_PS; + if (!isatty(STDIN_FILENO)) + prompt = ""; + + while (!exit_flag) { + char *str = readline(stdin, prompt); + if (str == NULL) + break; + + char **tok = tokenize(str); + + int status = execute(tok, envp); + if (status) + setenv("status", "1", 1); + + else + setenv("status", "0", 1); + + free(tok); + free(str); + } + + putchar('\n'); return 0; } diff --git a/sysutils/mount.c b/sysutils/mount.c new file mode 100644 index 0000000..4c8c128 --- /dev/null +++ b/sysutils/mount.c @@ -0,0 +1,18 @@ +#include +#include +#include +#include +#include "config.h" + +int main(int argc, char **argv) { + int opt; + while ((opt = getopt(argc, argv, "aro")) != -1) { + switch (opt) { + default: + printf("mount [DEVICE] [NODE]\n\t[-r Read only] [-o Options]\n\t[-a Mount all fs in %s]\n\nOptions:\n\tremount - Remount a mounted filesystem\n\tro - Read only\n", MOUNT_CFG); + return 0; + } + } + + return 0; +}