Compare commits
No commits in common. "8285e148e170b4b6b3e89b98c1747171b65be1a4" and "db5aef12c2d28788bd72b652b9d6a30592865bda" have entirely different histories.
8285e148e1
...
db5aef12c2
2 changed files with 9 additions and 65 deletions
|
|
@ -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
|
||||
|
|
|
|||
72
main.c
72
main.c
|
|
@ -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, target);
|
||||
if (fd > 2) close(fd); //if file
|
||||
}
|
||||
dup2(fd, STDIN_FILENO);
|
||||
}
|
||||
if ((fd = command->redirect[1]) != -1)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue