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 * Features
- Can run commands - Can run commands
- You can pipe stdout of one command to stdin of another (ex. ~cat main.c | wc --lines~) - 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 - 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) - Run subcomands with ~$(hostname)~ or ~`pwd`~ (works with pipes)
- ~cd~ builtin command (~cd~ without arguments moves you to ~$HOME~) - ~cd~ builtin command (~cd~ without arguments moves you to ~$HOME~)
- ~exit~ builtin command - ~exit~ builtin command

70
main.c
View file

@ -7,7 +7,6 @@
#include <signal.h> #include <signal.h>
#include <setjmp.h> #include <setjmp.h>
#include <ctype.h> #include <ctype.h>
#include <fcntl.h>
constexpr size_t max_length = 1024; constexpr size_t max_length = 1024;
constexpr size_t max_env_var_length = 256; 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. * IO redirections; redirect[i] should be used as fd i in the child.
* A value of -1 indicates no redirect. * A value of -1 indicates no redirect.
*/ */
int redirect[3]; int redirect[2];
/** The arguments; must be NULL-terminated. */ /** The arguments; must be NULL-terminated. */
char* argv[]; char* argv[];
}; };
@ -359,13 +358,6 @@ char* parse_token(char** input)
return buf; 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. * 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. * 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); struct command* ret = ccalloc(sizeof(struct command) + strlen(copy) * sizeof(char*), 1);
parser_allocated(ret); parser_allocated(ret);
ret->redirect[0] = ret->redirect[1] = ret->redirect[2] = -1;
char* p = copy; char* p = copy;
while (*p) while (*p)
@ -397,47 +387,9 @@ struct command* parse_command(char* str)
if (!token) if (!token)
break; 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->argv[i++] = token;
} }
ret->redirect[0] = ret->redirect[1] = -1;
return ret; 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]) 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); dup2(fd, STDOUT_FILENO);
if (fd > 2) close(fd); //if file
} }
}
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); close_ALL_the_pipes(n_pipes, pipes);
return execvp(command_name(command), command->argv); 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 cd(char* path)
{ {
int result = chdir(path); int result = chdir(path);
if(result < 0)
{
return result;
}
char cwd[max_length]; char cwd[max_length];
if (getcwd(cwd, sizeof(cwd)) != NULL) if (getcwd(cwd, sizeof(cwd)) != NULL)
{ {