Compare commits

..

No commits in common. "8285e148e170b4b6b3e89b98c1747171b65be1a4" and "db5aef12c2d28788bd72b652b9d6a30592865bda" have entirely different histories.

2 changed files with 9 additions and 65 deletions

View file

@ -4,9 +4,7 @@ Simple shell for Unix-like systems written in C, that has a funny name (for germ
* Features
- Can run commands
- You can pipe stdout of one command to stdin of another (ex. ~cat main.c | wc --lines~)
- Your can redirrect output/input with ~>~, ~>>~, ~<~, ~2>~, ~&>~
- Variables expansion with ~$PATH~ and ~${HOME}~ syntax
- Shows custom prompt, if ~PS1~ env variable is set
- Run subcomands with ~$(hostname)~ or ~`pwd`~ (works with pipes)
- ~cd~ builtin command (~cd~ without arguments moves you to ~$HOME~)
- ~exit~ builtin command

70
main.c
View file

@ -7,7 +7,6 @@
#include <signal.h>
#include <setjmp.h>
#include <ctype.h>
#include <fcntl.h>
constexpr size_t max_length = 1024;
constexpr size_t max_env_var_length = 256;
@ -87,7 +86,7 @@ struct command
* IO redirections; redirect[i] should be used as fd i in the child.
* A value of -1 indicates no redirect.
*/
int redirect[3];
int redirect[2];
/** The arguments; must be NULL-terminated. */
char* argv[];
};
@ -359,13 +358,6 @@ char* parse_token(char** input)
return buf;
}
int open_fout(const char* file, bool append)
{
return open(file,
O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC),
0644);
}
/**
* Parses str into a freshly allocated command struct and returns a pointer to it.
* The redirects in the returned command will be set to -1, ie no redirect.
@ -386,8 +378,6 @@ struct command* parse_command(char* str)
struct command* ret = ccalloc(sizeof(struct command) + strlen(copy) * sizeof(char*), 1);
parser_allocated(ret);
ret->redirect[0] = ret->redirect[1] = ret->redirect[2] = -1;
char* p = copy;
while (*p)
@ -397,47 +387,9 @@ struct command* parse_command(char* str)
if (!token)
break;
if (strcmp(token, ">") == 0)
{
char* file = parse_token(&p);
int fd = open_fout(file, false);
ret->redirect[STDOUT_FILENO] = fd;
continue;
}
if (strcmp(token, ">>") == 0)
{
char* file = parse_token(&p);
int fd = open_fout(file, true);
ret->redirect[STDOUT_FILENO] = fd;
continue;
}
if (strcmp(token, "<") == 0)
{
char* file = parse_token(&p);
int fd = open(file, O_RDONLY);
ret->redirect[STDIN_FILENO] = fd;
continue;
}
if (strcmp(token, "2>") == 0)
{
char* file = parse_token(&p);
int fd = open_fout(file, false);
ret->redirect[STDERR_FILENO] = fd;
continue;
}
if (strcmp(token, "&>") == 0)
{
char* file = parse_token(&p);
int fd = open_fout(file, false);
ret->redirect[STDOUT_FILENO] = fd;
ret->redirect[STDERR_FILENO] = fd;
continue;
}
ret->argv[i++] = token;
}
ret->redirect[0] = ret->redirect[1] = -1;
return ret;
}
@ -543,17 +495,15 @@ void close_ALL_the_pipes(int n_pipes, int (*pipes)[2])
int exec_with_redir(struct command* command, int n_pipes, int (*pipes)[2])
{
void apply_redir(int fd, int target)
int fd = -1;
if ((fd = command->redirect[0]) != -1)
{
if (fd != -1)
dup2(fd, STDIN_FILENO);
}
if ((fd = command->redirect[1]) != -1)
{
dup2(fd, target);
if (fd > 2) close(fd); //if file
dup2(fd, STDOUT_FILENO);
}
}
apply_redir(command->redirect[0], STDIN_FILENO);
apply_redir(command->redirect[1], STDOUT_FILENO);
apply_redir(command->redirect[2], STDERR_FILENO);
close_ALL_the_pipes(n_pipes, pipes);
return execvp(command_name(command), command->argv);
}
@ -586,10 +536,6 @@ pid_t run_with_redir(struct command* command, int n_pipes, int (*pipes)[2])
int cd(char* path)
{
int result = chdir(path);
if(result < 0)
{
return result;
}
char cwd[max_length];
if (getcwd(cwd, sizeof(cwd)) != NULL)
{