Re-opening stdout and stdin file descriptors after closing them

You should use dup() and dup2() to clone a file descriptor.

int stdin_copy = dup(0);
int stdout_copy = dup(1);
close(0);
close(1);

int file1 = open(...);
int file2 = open(...);

< do your work. file1 and file2 must be 0 and 1, because open always returns lowest unused fd >

close(file1);
close(file2);
dup2(stdin_copy, 0);
dup2(stdout_copy, 1);
close(stdin_copy);
close(stdout_copy);

However, there’s a minor detail you might want to be careful with (from man dup):

The two descriptors do not share file descriptor flags (the
close-on-execflag). The close-on-exec flag (FD_CLOEXEC; see fcntl(2))
for the duplicate descriptor is off.

If this is a problem, you might have to restore the close-on-exec flag, possibly using dup3() instead of dup2() to avoid race conditions.

Also, be aware that if your program is multi-threaded, other threads may accidentally write/read to your remapped stdin/stdout.

Leave a Comment