Back to home

A simple exampleA more readable exampleResources
Unix Redirection In C main image

Unix Redirection In C

This short post is a recount of an exploration into redirection in the C language.

As always, let's go to our friend Wikipedia to set the definition for us:

Basic redirection can use < to redirect input and > to redirect output.

For example, we can use the redirect output operator to redirect the output from echo "Hello!" into a file example.txt.

1 2 3 > echo "Hello!" > example.txt > cat example.txt Hello!

As mentioned by our pal Wikipedia, we can use the dup2 system call in C to manage a similar thing!

A simple example

In our first example, we are going to write a simple example of two variables that open a foobar.txt that iterates character by character.

1 touch foobar.txt one.c

Inside of foobar.txt, add th following:

1 foobar test

As for the contents of one.c:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> int main() { int fd1, fd2; char c; fd1 = open("foobar.txt", O_RDONLY); fd2 = open("foobar.txt", O_RDONLY); // c becomes f read(fd2, &c, 1); // c becomes o read(fd2, &c, 1); // c becomes o read(fd2, &c, 1); // c becomes b read(fd2, &c, 1); printf("c = %c\n", c); // c = b // now reading in fd1, so c becomes f again read(fd1, &c, 1); printf("c = %c\n", c); // c = f // redirect and now fd2 is now back at f dup2(fd1, fd2); // reading back fd2 which has been redirected, // so c actually becomes o! read(fd2, &c, 1); printf("c = %c\n", c); // c = 0 exit(0); }

The comments in the code explain what is happening in order, but we're just going to print out the result by running gcc one.c && ./a.out. The output binary a.out is the name given since we do not provide output to GCC.

1 2 3 4 > gcc one.c && ./a.out c = b c = f c = o

To explain further what is going on:

  1. We assign fd1 and fd2 to open foobar.txt.
  2. We use read to read in a character and assign it to variable c.
  3. Each time we read fd2, we move one character further along in the text file.
  4. Eventually, we read fd1 once and then we redirectfd1 to fd2.
  5. We read fd2 one last time, but after redirection the value now reads "o".

A more readable example

The above can seem hard to comprehend - it is better playing around with this stuff in C. This example, I decided to use scanf to read in from stdin in the second example, because I feel like the example was a little clearer for me.

Create a file two.c.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #define STR_LEN 6 int main() { int fd1; char *c1 = (char*)malloc(STR_LEN); char *c2 = (char*)malloc(STR_LEN); // notice no values printf("c1 = %s\nc2 = %s\n", c1, c2); fd1 = open("foobar.txt", O_RDONLY); // redirect fd1 to stdin if (dup2(fd1, STDIN_FILENO) < 0) { printf("Unable to duplicate file descriptor."); exit(EXIT_FAILURE); } // scan c1 and c2 in from stdin scanf("%s %s", c1, c2); // values now becomes "foobar" and "test" respectively printf("c1 = %s\nc2 = %s\n", c1, c2); // SAVE THE WHALES, FREE THE MALLOCS free(c1); free(c2); exit(0); }

Now if we run gcc two.c && ./a.out, we get the following:

1 2 3 4 5 > gcc two.c && ./a.out c1 = c2 = c1 = foobar c2 = test

In this case, we do the following:

  1. Allocate memory for c1 and c2.
  2. Confirm no values in first print.
  3. Read in the foobar.txt file to file descriptor fd1.
  4. Redirect fd1 to stdin.
  5. Use scanf to assign the values to c1 and c2 from stdin.
  6. Confirm with the last print that c1 and c2 have been assigned the words "foobar" and "test" respectively!

Hooray! Redirection to stdin is a success (and no segmentation faults).

I will likely redo this exercise in Rust and Golang this week to show the how-to.

Resources

Image credit: Michael Kubler

Dennis O'Keeffe

@dennisokeeffe92
  • Melbourne, Australia

Hi, I am a professional Software Engineer. Formerly of Culture Amp, UsabilityHub, Present Company and NightGuru.
I am currently working on workingoutloud.dev, Den Dribbles and LandPad .

Related articles


1,200+ PEOPLE ALREADY JOINED ❤️️

Get fresh posts + news direct to your inbox.

No spam. We only send you relevant content.