-
Notifications
You must be signed in to change notification settings - Fork 0
/
redirect.c
85 lines (75 loc) · 1.57 KB
/
redirect.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include "tinyshell.h"
static bool next_redirect_in(char ***arguments)
{
while (**arguments)
{
if (is_same(**arguments, "<"))
return (true);
(*arguments)++;
}
return (false);
}
static bool next_redirect_out(char ***arguments)
{
while (**arguments)
{
if (is_same(**arguments, ">") || is_same(**arguments, ">>"))
return (true);
(*arguments)++;
}
return (false);
}
static void redirect_in_from(const char *filename)
{
static int input;
if (input)
close(input);
input = open(filename, O_RDONLY, 0777);
if (input == ERROR)
exit_error("open");
dup2(input, STDIN_FILENO);
close(input);
}
static void redirect_out_to(const char *filename, int option)
{
static int output;
if (output)
close(output);
if (option == TRUNCATE)
output = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0777);
else
output = open(filename, O_WRONLY | O_CREAT | O_APPEND, 0777);
if (output == ERROR)
exit_error("open");
dup2(output, STDOUT_FILENO);
close(output);
}
bool redirect_in(char **arguments)
{
char *filename;
while (next_redirect_in(&arguments))
{
filename = strdup(arguments[1]);
if (!filename)
exit_error("redirect_in");
redirect_in_from(filename);
erase_from(arguments, 2);
free(filename);
}
return (true);
}
bool redirect_out(char **arguments)
{
char *filename;
while (next_redirect_out(&arguments))
{
filename = strdup(arguments[1]);
if (is_same(arguments[0], ">"))
redirect_out_to(filename, TRUNCATE);
else if (is_same(arguments[0], ">>"))
redirect_out_to(filename, APPEND);
erase_from(arguments, 2);
free(filename);
}
return (true);
}