92 lines
1.5 KiB
C
92 lines
1.5 KiB
C
#include "shell.h"
|
|
|
|
char** s_completion(const char* text, int start, int end) {
|
|
rl_attempted_completion_over = 1;
|
|
return rl_completion_matches(text, s_names);
|
|
}
|
|
|
|
void s_die(const char* msg) {
|
|
fprintf(stderr, "s: %s\n", msg);
|
|
exit(1);
|
|
}
|
|
|
|
int s_do(char **args) {
|
|
pid_t pid, wpid;
|
|
int s;
|
|
|
|
pid = fork();
|
|
if (!pid) {
|
|
if (execvp(args[0], args) == -1) perror(args[0]);
|
|
exit(EXIT_FAILURE);
|
|
} else if (pid < 0) {
|
|
// Error forking
|
|
perror(args[0]);
|
|
} else {
|
|
do {
|
|
wpid = waitpid(pid, &s, WUNTRACED);
|
|
} while (!WIFEXITED(s) && !WIFSIGNALED(s));
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
char** s_prompt() {
|
|
char* line = readline("> ");
|
|
int bs = 64;
|
|
int pos = 0;
|
|
char **tokens = malloc(bs * sizeof(char*));
|
|
char *token;
|
|
|
|
|
|
if (!line) return NULL;
|
|
|
|
add_history(line);
|
|
|
|
if (!tokens) s_die("allocation error");
|
|
|
|
token = strtok(line, " \t\r\n\a");
|
|
|
|
while (token) {
|
|
tokens[pos++] = token;
|
|
|
|
if (pos >= bs) {
|
|
bs += 64;
|
|
tokens = realloc(tokens, bs * sizeof(char*));
|
|
if (!tokens) s_die("allocation error");
|
|
}
|
|
|
|
token = strtok(NULL, " \t\r\n\a");
|
|
}
|
|
tokens[pos] = NULL;
|
|
|
|
free(line);
|
|
return tokens;
|
|
}
|
|
|
|
int s_exec(char** args) {
|
|
int i;
|
|
|
|
if (!args[0]) return 1;
|
|
|
|
for (i = 0; i < s_builtins_count(); i++) {
|
|
if (!strcmp(args[0], s_builtin_names[i])) return (*s_builtins[i])(args);
|
|
}
|
|
|
|
return s_do(args);
|
|
}
|
|
|
|
void s_loop() {
|
|
rl_attempted_completion_function = s_completion;
|
|
|
|
char** cmd;
|
|
int s;
|
|
|
|
do {
|
|
cmd = s_prompt();
|
|
if(!cmd) return;
|
|
s = s_exec(cmd);
|
|
free(cmd);
|
|
} while(s);
|
|
}
|