Teodor Dyakov
Teodor Dyakov

Reputation: 352

Why do I need to use dup for stdout redirection if the same can be achieved without it?

I am learning about redirection in Linux via system calls. A common way to redirect stdout to a file "foo.txt" is to do it like so:

int fd = creat("foo.txt", 0644);    
close(1);
dup(fd);
close(fd);
execlp("ls", "ls", NULL);

However I empirically found out that we can achieve the same thing without even using dup.

close(1);
creat("foo.txt", 0644); 
execlp("ls", "ls", NULL);   

The second example will work correctly every time because creat always returns the lowest unused file descriptor. I am wondering why every example I have seen prefers the first way if the secnods is simpler?

Upvotes: 0

Views: 268

Answers (1)

that other guy
that other guy

Reputation: 123550

Both of these examples are buggy because they both rely on the same invalid assumption that closing 1 makes 1 the lowest available FD.

You can trivially invalidate this assumption, causing the program to fail:

$ cat foo.c
#include <fcntl.h>
#include <unistd.h>

void main() {
  close(1);
  creat("foo.txt", 0644);
  execlp("ls", "ls", NULL);
}

$ gcc foo.c -o foo

$ ./foo 0>&-
ls: write error: Bad file descriptor

The way to deal with this is to use dup2 to explicitly pick the fd you want:

void main() {
  int fd = creat("foo.txt", 0644);
  if (fd != 1) {
    dup2(fd, 1);
    close(fd);
  }
  execlp("ls", "ls", NULL);
}

Upvotes: 2

Related Questions