Redirecting stdin and stderr in C on Linux

By gracefu on

Suppose you're forking and execling to a new process, but you want to make sure that this new process does not see your stdin. Or maybe, you don't want its stderr to be printed.

You can silence it by redirecting them both to /dev/null. One way to do that is:

if (!fork()) {
  // We're in the child process

  // Close STDIN_FILENO (0)
  close(0);

  // open() will use the lowest numbered available file descriptor, which is 0
  open("/dev/null", O_RDWR);

  // Map STDERR_FILENO (2) to the same file as STDIN_FILENO (0), which is /dev/null
  dup2(0, 2);

  // ... the rest of your setup, and then execl ...
}

Pretty neat! For only 3 syscalls, we have redirected 2 file descriptors at the same time.

If we only had to redirect one of them, we only need 2 syscalls to first close then to open in place.

We do want to make sure to do these steps after the fork, not only to make sure the file descriptor table of the parent process is left untouched, but also to make sure that the current process is single threaded. That way, we can be sure that the close - open pattern will not suffer from some race condition.

Back to home page