redirect.c

Download
c 174 lines 4.3 KB
  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