KoreanFoodie's Study

Implement a simple linux shell with pipe and more! 본문


Implement a simple linux shell with pipe and more!

GoldGiver 2019. 4. 23. 14:47

Implement a simple linux shell with pipe and more!

리눅스 쉘에서 파이프, 리다이렉션을 구현해 보자

I'm going to present how to solve execercise 11, chapter3, from Operating Systems: Principles & Practice,2nd Edition.

Problem specificatoin : implement a simple linux shell in c capable of executing a sequence of programs that communicate through a pipe. For example, if the user types ls | wc...

So the problem is how to implement ls | wc, which calculate the number of files in the given directory.

You need to direct stdout of ls to stdin of wc by using pipe. This can be implemented using simple linux system calls.

Here's a sample code.

int main(int argc, char **argv) {
    int pipefd[2];
    int pid;
    char *ls_args[] = {"ld", NULL}
    char *wc_argx[] = {"wc", NULL}

    // make a pipe (fds go in pipefd[0] and pipefd[1])
    pid = fork();
    if (pid == 0) {
        // child process gets here! -> handles "wc"
        // replace standard input with input part of pipe pipefd[0]
        dup2(pipefd[0], 0);
        // close unused half(write side) of pipe
        // excute wc
        execvp("wc", wc_args);
    } else {
        // parent gets here! -> handles "ls"
        // replace standard output with output part of pipe pipefd[1]
        dup2(pipefd[1], 1);
        // close unused input half (read side) of pipe
        // execute ls
        execvp("ls", ls_args);

How to Implemente Redirection

So, now we're done with pipe, let's move on to the redirection(>, <).

How can we implement grep kernel < README > out.txt? (shell read README, find lines which contains keyword kernel, and then it writes it into out.txt)

Here's how I did it.

int main(int argc, char **argv) {
    int in, out;
    char *grep_args = ["grep", "kernel", NULL];  

    in = open("README", O_RDONLY);
    out = open("out.txt", O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IRGRP | S_IWGRP | S_IWUSR);

    // replace stdin to in
    dup2(in, 0);
    // replace stdout to out
    dup2(out, 1);

    // close unused file descriptors
    // execute grep
    execvp("grep", grep_args);


To test this actually works, make a simple README file and run this code.

Example output :

This is the solution to Operating Systems: Principles & Practice,2nd Edition, chapter3, exercise 11.