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
|
* 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
70
main.c
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue