#include <sys/wait.h>
#include <sys/types.h>
-#define LSH_TOK_BUFSIZE 64
-#define LSH_TOK_DELIM " \t\r\n\a"
-
-int cd(char **args)
-{
- if (args[1] == NULL)
- {
- fprintf(stderr, "lsh: expected argument to \"cd\"\n");
- }
- else
- {
- if (chdir(args[1]) != 0)
- {
- perror("lsh");
- }
- }
- return 1;
-}
-
-struct {
- char* name;
- int (*func)(char**);
-} Builtins[] = {
- { .name = "cd", .func = cd }
-};
-
-int launch(char **args)
-{
- pid_t pid = fork();
- if (pid == 0)
- {
- // Child process
- if (execvp(args[0], args) == -1)
- {
- perror("lsh");
- }
- exit(EXIT_FAILURE);
- }
- else if (pid < 0)
- {
- // Error forking
- perror("lsh");
- }
- else
- {
- int status;
- do
- {
- waitpid(pid, &status, WUNTRACED);
- } while (!WIFEXITED(status) && !WIFSIGNALED(status));
- }
-
- return 1;
-}
-
-int execute(char **args)
-{
- if (args[0] == NULL)
- {
- // An empty command was entered.
- return 1;
- }
-
- for (size_t i = 0; i < nelem(Builtins); i++)
- {
- if (!strcmp(args[0], Builtins[i].name))
- {
- return Builtins[i].func(args);
- }
- }
-
- return launch(args);
-}
-
-/**
- @brief Read a line of input from stdin.
- @return The line from stdin.
- */
-char *read_line(void)
+char* read_line(FILE* f)
{
- char *line = NULL;
- size_t bufsize = 0; // have getline allocate a buffer for us
- if (getline(&line, &bufsize, stdin) == -1)
+ char* line = efreadline(stdin);
+ size_t length = strlen(line);
+ if (length > 0 && line[length-1] == '\n')
{
- if (feof(stdin))
- {
- exit(EXIT_SUCCESS); // We recieved an EOF
- }
- else
+ line[--length] = '\0';
+ if (length > 0 && line[length-1] == '\\')
{
- perror("lsh: getline\n");
- exit(EXIT_FAILURE);
+ line[--length] = ' ';
+ char* rest = read_line(f);
+ char* lnpart = strmcat(line, rest, 0);
+ free(line);
+ free(rest);
+ line = lnpart;
}
}
return line;
}
-
-char** split_line(char *line)
-{
- int bufsize = LSH_TOK_BUFSIZE, position = 0;
- char **tokens = malloc(bufsize * sizeof(char*));
- char *token, **tokens_backup;
-
- if (!tokens)
- {
- fprintf(stderr, "lsh: allocation error\n");
- exit(EXIT_FAILURE);
- }
-
- token = strtok(line, LSH_TOK_DELIM);
- while (token != NULL)
- {
- tokens[position] = token;
- position++;
-
- if (position >= bufsize)
- {
- bufsize += LSH_TOK_BUFSIZE;
- tokens_backup = tokens;
- tokens = realloc(tokens, bufsize * sizeof(char*));
- if (!tokens)
- {
- free(tokens_backup);
- fprintf(stderr, "lsh: allocation error\n");
- exit(EXIT_FAILURE);
- }
- }
-
- token = strtok(NULL, LSH_TOK_DELIM);
- }
- tokens[position] = NULL;
- return tokens;
-}
-
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
- // Load config files, if any.
+ /* load config files... */
- int status = 0;
+ int running = 1;
do
{
printf("> ");
- char* line = read_line();
- char** args = split_line(line);
- status = execute(args);
- (void)status;
+ char* line = read_line(stdin);
+ printf("'%s'\n", line);
free(line);
- free(args);
}
- while (status);
+ while (running);
- // Perform any shutdown/cleanup.
+ /* shutdown and cleanup */
- return EXIT_SUCCESS;
+ return 0;
}
-