1// redirect.c
2// ์
์ถ๋ ฅ ๋ฆฌ๋ค์ด๋ ์
๊ตฌํ
3// > (์ถ๋ ฅ), >> (์ถ๊ฐ), < (์
๋ ฅ) ์ฐ์ฐ์ ์ฒ๋ฆฌ
4// ์ปดํ์ผ: gcc -c redirect.c ๋๋ ๋ค๋ฅธ ํ์ผ๊ณผ ํจ๊ป ๋งํฌ
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include <fcntl.h>
10#include <unistd.h>
11#include <sys/wait.h>
12
13typedef struct {
14 char* input_file; // < ํ์ผ
15 char* output_file; // > ๋๋ >> ํ์ผ
16 int append; // >> ์ธ ๊ฒฝ์ฐ 1
17} Redirect;
18
19// ๋ฆฌ๋ค์ด๋ ์
ํ์ฑ
20// args์์ ๋ฆฌ๋ค์ด๋ ์
์ ๊ฑฐํ๊ณ Redirect ๊ตฌ์กฐ์ฒด์ ์ ์ฅ
21void parse_redirect(char** args, Redirect* redir) {
22 redir->input_file = NULL;
23 redir->output_file = NULL;
24 redir->append = 0;
25
26 int i = 0;
27 int j = 0;
28
29 while (args[i] != NULL) {
30 if (strcmp(args[i], "<") == 0) {
31 // ์
๋ ฅ ๋ฆฌ๋ค์ด๋ ์
32 if (args[i + 1]) {
33 redir->input_file = args[i + 1];
34 i += 2;
35 continue;
36 }
37 } else if (strcmp(args[i], ">") == 0) {
38 // ์ถ๋ ฅ ๋ฆฌ๋ค์ด๋ ์
(๋ฎ์ด์ฐ๊ธฐ)
39 if (args[i + 1]) {
40 redir->output_file = args[i + 1];
41 redir->append = 0;
42 i += 2;
43 continue;
44 }
45 } else if (strcmp(args[i], ">>") == 0) {
46 // ์ถ๋ ฅ ๋ฆฌ๋ค์ด๋ ์
(์ถ๊ฐ)
47 if (args[i + 1]) {
48 redir->output_file = args[i + 1];
49 redir->append = 1;
50 i += 2;
51 continue;
52 }
53 }
54
55 // ๋ฆฌ๋ค์ด๋ ์
์ด ์๋ ์ธ์
56 args[j++] = args[i++];
57 }
58 args[j] = NULL;
59}
60
61// ๋ฆฌ๋ค์ด๋ ์
์ ์ฉ (์์ ํ๋ก์ธ์ค์์ ํธ์ถ)
62int apply_redirect(Redirect* redir) {
63 // ์
๋ ฅ ๋ฆฌ๋ค์ด๋ ์
64 if (redir->input_file) {
65 int fd = open(redir->input_file, O_RDONLY);
66 if (fd < 0) {
67 perror(redir->input_file);
68 return -1;
69 }
70 dup2(fd, STDIN_FILENO);
71 close(fd);
72 }
73
74 // ์ถ๋ ฅ ๋ฆฌ๋ค์ด๋ ์
75 if (redir->output_file) {
76 int flags = O_WRONLY | O_CREAT;
77 flags |= redir->append ? O_APPEND : O_TRUNC;
78
79 int fd = open(redir->output_file, flags, 0644);
80 if (fd < 0) {
81 perror(redir->output_file);
82 return -1;
83 }
84 dup2(fd, STDOUT_FILENO);
85 close(fd);
86 }
87
88 return 0;
89}
90
91// ๋ฆฌ๋ค์ด๋ ์
์ ํฌํจํ ๋ช
๋ น์ด ์คํ
92void execute_with_redirect(char** args) {
93 Redirect redir;
94 parse_redirect(args, &redir);
95
96 if (args[0] == NULL) return;
97
98 pid_t pid = fork();
99
100 if (pid == 0) {
101 // ์์: ๋ฆฌ๋ค์ด๋ ์
์ ์ฉ ํ ์คํ
102 if (apply_redirect(&redir) < 0) {
103 exit(EXIT_FAILURE);
104 }
105 execvp(args[0], args);
106 perror(args[0]);
107 exit(EXIT_FAILURE);
108 } else if (pid > 0) {
109 int status;
110 waitpid(pid, &status, 0);
111 } else {
112 perror("fork");
113 }
114}
115
116// ํ
์คํธ์ฉ ๋ฉ์ธ ํจ์
117#ifdef TEST_REDIRECT
118#define MAX_INPUT 1024
119#define MAX_ARGS 64
120
121int parse_args(char* input, char** args) {
122 int argc = 0;
123 char* token = strtok(input, " \t\n");
124 while (token && argc < MAX_ARGS - 1) {
125 args[argc++] = token;
126 token = strtok(NULL, " \t\n");
127 }
128 args[argc] = NULL;
129 return argc;
130}
131
132int main(void) {
133 char input[MAX_INPUT];
134 char* args[MAX_ARGS];
135
136 printf("=== ๋ฆฌ๋ค์ด๋ ์
ํ
์คํธ ===\n");
137 printf("์์ ๋ช
๋ น์ด:\n");
138 printf(" ls -l > output.txt\n");
139 printf(" cat < input.txt\n");
140 printf(" echo \"Hello\" >> output.txt\n");
141 printf(" wc -l < /etc/passwd\n");
142 printf("\n์ข
๋ฃ: exit ๋๋ Ctrl+D\n\n");
143
144 while (1) {
145 printf("redirect> ");
146 fflush(stdout);
147
148 if (fgets(input, sizeof(input), stdin) == NULL) {
149 printf("\n");
150 break;
151 }
152
153 if (input[0] == '\n') continue;
154
155 // ์
๋ ฅ ๋ณต์ฌ (strtok์ด ์๋ณธ ์์ )
156 char input_copy[MAX_INPUT];
157 strncpy(input_copy, input, sizeof(input_copy));
158
159 int argc = parse_args(input_copy, args);
160 if (argc == 0) continue;
161
162 if (strcmp(args[0], "exit") == 0) {
163 printf("์ข
๋ฃํฉ๋๋ค.\n");
164 break;
165 }
166
167 // ๋ฆฌ๋ค์ด๋ ์
ํฌํจ ์คํ
168 execute_with_redirect(args);
169 }
170
171 return 0;
172}
173#endif