Search code examples
clinuxunix

How do I make a Linux C program that supports piping in to it via the shell?


There are certain programs in Linux that can take input from other programs with a syntax like this:

echo neofetch | pacman -S -

which will pipe "neofetch" into pacman in place of the single dash, resulting in it installing neofetch. How can I make my own C program for Linux that supports this syntax?

I already know that to take piped input into a program you would use stdin, but i don't know how to do that. I have not found any other info on this topic, only stuff about pipe(), which doesn't seem to be the way to do this.


Solution

  • Any function that reads from stdin will read from this pipe. That's the point of stdin. For example, this program would read a character at a time from stdin and write it to stdout. With |, the stdout of echo will be attached to the stdin of this program:

    int main() {
        char c;
        while ((c = getchar()) != EOF) {
            putchar(c);
        }
        return 0;
    }
    

    Anything that can read stdin (fileno 0) works this way. read, scanf, etc. For example, using fread in chunks of 100 bytes from stdin and writing them to stdout:

    int main() {
        char buffer[100];
        size_t bytesRead;
        while ((bytesRead = fread(buffer, 1, 100, stdin)) > 0) {
            fwrite(buffer, 1, bytesRead, stdout);
        }
        return 0;
    }
    

    A core design philosophy of Unix is that "everything is a file." So the output of the left side of the pipe is a "file" (a fake file) called stdout, and the right side is the same, called stdin. The "pipe" carries data between the two.