pipe.c

Download
c 177 lines 4.2 KB
  1// pipe.c
  2// ํŒŒ์ดํ”„ ๊ตฌํ˜„
  3// ์—ฌ๋Ÿฌ ๋ช…๋ น์–ด๋ฅผ | ๋กœ ์—ฐ๊ฒฐํ•˜์—ฌ ์‹คํ–‰
  4// ์ปดํŒŒ์ผ: gcc -c pipe.c ๋˜๋Š” ๋‹ค๋ฅธ ํŒŒ์ผ๊ณผ ํ•จ๊ป˜ ๋งํฌ
  5
  6#include <stdio.h>
  7#include <stdlib.h>
  8#include <string.h>
  9#include <unistd.h>
 10#include <sys/wait.h>
 11
 12#define MAX_PIPES 10
 13
 14// ํŒŒ์ดํ”„๋กœ ๋ถ„๋ฆฌ๋œ ๋ช…๋ น์–ด ์ˆ˜ ์นด์šดํŠธ
 15int count_pipes(char** args) {
 16    int count = 0;
 17    for (int i = 0; args[i]; i++) {
 18        if (strcmp(args[i], "|") == 0) count++;
 19    }
 20    return count;
 21}
 22
 23// ํŒŒ์ดํ”„ ์œ„์น˜์—์„œ args ๋ถ„๋ฆฌ
 24// commands[0] = ์ฒซ ๋ฒˆ์งธ ๋ช…๋ น์–ด์˜ args
 25// commands[1] = ๋‘ ๋ฒˆ์งธ ๋ช…๋ น์–ด์˜ args
 26// ...
 27int split_by_pipe(char** args, char*** commands) {
 28    int cmd_count = 0;
 29    commands[cmd_count++] = args;
 30
 31    for (int i = 0; args[i]; i++) {
 32        if (strcmp(args[i], "|") == 0) {
 33            args[i] = NULL;  // ํŒŒ์ดํ”„ ์œ„์น˜๋ฅผ NULL๋กœ
 34            if (args[i + 1]) {
 35                commands[cmd_count++] = &args[i + 1];
 36            }
 37        }
 38    }
 39
 40    return cmd_count;
 41}
 42
 43// ํŒŒ์ดํ”„ ์‹คํ–‰
 44void execute_pipe(char** args) {
 45    char** commands[MAX_PIPES + 1];
 46    int cmd_count = split_by_pipe(args, commands);
 47
 48    if (cmd_count == 1) {
 49        // ํŒŒ์ดํ”„ ์—†์Œ: ์ผ๋ฐ˜ ์‹คํ–‰
 50        pid_t pid = fork();
 51        if (pid == 0) {
 52            execvp(commands[0][0], commands[0]);
 53            perror(commands[0][0]);
 54            exit(EXIT_FAILURE);
 55        } else if (pid > 0) {
 56            wait(NULL);
 57        } else {
 58            perror("fork");
 59        }
 60        return;
 61    }
 62
 63    int pipes[MAX_PIPES][2];  // ํŒŒ์ดํ”„ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ
 64
 65    // ํŒŒ์ดํ”„ ์ƒ์„ฑ
 66    for (int i = 0; i < cmd_count - 1; i++) {
 67        if (pipe(pipes[i]) < 0) {
 68            perror("pipe");
 69            return;
 70        }
 71    }
 72
 73    // ๊ฐ ๋ช…๋ น์–ด ์‹คํ–‰
 74    for (int i = 0; i < cmd_count; i++) {
 75        pid_t pid = fork();
 76
 77        if (pid == 0) {
 78            // ์ž์‹ ํ”„๋กœ์„ธ์Šค
 79
 80            // ์ด์ „ ํŒŒ์ดํ”„์˜ ์ฝ๊ธฐ ๋์„ stdin์œผ๋กœ
 81            if (i > 0) {
 82                dup2(pipes[i - 1][0], STDIN_FILENO);
 83            }
 84
 85            // ๋‹ค์Œ ํŒŒ์ดํ”„์˜ ์“ฐ๊ธฐ ๋์„ stdout์œผ๋กœ
 86            if (i < cmd_count - 1) {
 87                dup2(pipes[i][1], STDOUT_FILENO);
 88            }
 89
 90            // ๋ชจ๋“  ํŒŒ์ดํ”„ ๋‹ซ๊ธฐ
 91            for (int j = 0; j < cmd_count - 1; j++) {
 92                close(pipes[j][0]);
 93                close(pipes[j][1]);
 94            }
 95
 96            // ๋ช…๋ น์–ด ์‹คํ–‰
 97            execvp(commands[i][0], commands[i]);
 98            perror(commands[i][0]);
 99            exit(EXIT_FAILURE);
100
101        } else if (pid < 0) {
102            perror("fork");
103            return;
104        }
105    }
106
107    // ๋ถ€๋ชจ: ๋ชจ๋“  ํŒŒ์ดํ”„ ๋‹ซ๊ธฐ
108    for (int i = 0; i < cmd_count - 1; i++) {
109        close(pipes[i][0]);
110        close(pipes[i][1]);
111    }
112
113    // ๋ชจ๋“  ์ž์‹ ํ”„๋กœ์„ธ์Šค ๋Œ€๊ธฐ
114    for (int i = 0; i < cmd_count; i++) {
115        wait(NULL);
116    }
117}
118
119// ํ…Œ์ŠคํŠธ์šฉ ๋ฉ”์ธ ํ•จ์ˆ˜
120#ifdef TEST_PIPE
121#define MAX_INPUT 1024
122#define MAX_ARGS 64
123
124int parse_args(char* input, char** args) {
125    int argc = 0;
126    char* token = strtok(input, " \t\n");
127    while (token && argc < MAX_ARGS - 1) {
128        args[argc++] = token;
129        token = strtok(NULL, " \t\n");
130    }
131    args[argc] = NULL;
132    return argc;
133}
134
135int main(void) {
136    char input[MAX_INPUT];
137    char* args[MAX_ARGS];
138
139    printf("=== ํŒŒ์ดํ”„ ํ…Œ์ŠคํŠธ ===\n");
140    printf("์˜ˆ์ œ ๋ช…๋ น์–ด:\n");
141    printf("  ls -l | grep \".c\"\n");
142    printf("  cat /etc/passwd | wc -l\n");
143    printf("  ps aux | grep bash | head -5\n");
144    printf("  ls | sort | uniq\n");
145    printf("\n์ข…๋ฃŒ: exit ๋˜๋Š” Ctrl+D\n\n");
146
147    while (1) {
148        printf("pipe> ");
149        fflush(stdout);
150
151        if (fgets(input, sizeof(input), stdin) == NULL) {
152            printf("\n");
153            break;
154        }
155
156        if (input[0] == '\n') continue;
157
158        // ์ž…๋ ฅ ๋ณต์‚ฌ
159        char input_copy[MAX_INPUT];
160        strncpy(input_copy, input, sizeof(input_copy));
161
162        int argc = parse_args(input_copy, args);
163        if (argc == 0) continue;
164
165        if (strcmp(args[0], "exit") == 0) {
166            printf("์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.\n");
167            break;
168        }
169
170        // ํŒŒ์ดํ”„ ์‹คํ–‰
171        execute_pipe(args);
172    }
173
174    return 0;
175}
176#endif