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.


I think you can "save" the descriptors before redirecting:

int save_in, save_out;

save_in = dup(STDIN_FILENO);
save_out = dup(STDOUT_FILENO);

Later on you can use dup2 to restore them:

/* Time passes, STDIN_FILENO isn't what it used to be. */
dup2(save_in, STDIN_FILENO);

I am not doing any error checking in that example - you should.


You could create a child process, and set up the redirection inside the child only. Then wait for the child to terminate, and continue working in the parent process. That way you don't have to worry about reversing your redirection at all.

Just look for examples of code using fork() and wait ().