Reputation: 352
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
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