Redirrect support for >, >>, <, &>, 2>
- cd does less work now
This commit is contained in:
parent
db5aef12c2
commit
17501b59b4
1 changed files with 63 additions and 9 deletions
72
main.c
72
main.c
|
|
@ -7,6 +7,7 @@
|
||||||
#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;
|
||||||
|
|
@ -86,7 +87,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[2];
|
int redirect[3];
|
||||||
/** The arguments; must be NULL-terminated. */
|
/** The arguments; must be NULL-terminated. */
|
||||||
char* argv[];
|
char* argv[];
|
||||||
};
|
};
|
||||||
|
|
@ -358,6 +359,13 @@ 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.
|
||||||
|
|
@ -378,6 +386,8 @@ 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)
|
||||||
|
|
@ -387,9 +397,47 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -495,15 +543,17 @@ 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])
|
||||||
{
|
{
|
||||||
int fd = -1;
|
void apply_redir(int fd, int target)
|
||||||
if ((fd = command->redirect[0]) != -1)
|
|
||||||
{
|
{
|
||||||
dup2(fd, STDIN_FILENO);
|
if (fd != -1)
|
||||||
}
|
{
|
||||||
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);
|
close_ALL_the_pipes(n_pipes, pipes);
|
||||||
return execvp(command_name(command), command->argv);
|
return execvp(command_name(command), command->argv);
|
||||||
}
|
}
|
||||||
|
|
@ -536,6 +586,10 @@ 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