How to recover stdin overwritten by dup2?
Asked Answered
E

1

5

I am trying to replace stdin with another pipe, then place the original stdin back to fd #0.

e.g.

dup2(p, 0); // p is a pre-existing fd of a pipe
exec(/* some commands */);

//what will be here in order to have the original stdin back?

scanf(...) //continue processing with original stdin.
Ezraezri answered 25/12, 2018 at 18:44 Comment(4)
Simply dup2() stdin to a temporary filedescriptor first and dup2() it back again laterZoubek
@Zoubek Is it possible to keep stdin without temporary duplicate it?Ezraezri
Not "keep" it, you could reopen it if it is possible. Depending on what your stdin is, this might be not possible however.Zoubek
The 'exec..()` commands do not return, unless they failed. So the only reasonable statements after an exec command are: perror( "exec.. failed" ); followed by exit( EXIT_FAILURE );Sexual
B
9

You can't recover the original once it has been overwritten (closed). What you can do is save a copy of it before you overwrite it (which requires planning ahead, of course):

int old_stdin = dup(STDIN_FILENO);

dup2(p, STDIN_FILENO);
close(p);               // Usually correct when you dup to a standard I/O file descriptor.

…code using stdin…

dup2(old_stdin, STDIN_FILENO);
close(old_stdin);       // Probably correct
scanf(…);

However, your code mentions exec(…some commands…); — if that is one of the POSIX execve() family of functions, then you won't reach the scanf() (or the second dup2()) call unless the exec*() call fails.

Bergquist answered 25/12, 2018 at 18:52 Comment(3)
Without duplicate the stdin to temporary fd, would you be able to reopen stdin?Ezraezri
In general, no. The original standard input might be a pipe, a socket, or some other fancy and ephemeral file type, which cannot be reopened. Plus you don't have a name to (re)open it with. After the dup2(p, STDIN_FILENO); operation succeeds, /dev/stdin is no help; it yields the file that p was opened for, not the original standard input.Bergquist
Also, while I think about it, note that you may run into problems with buffering of input if you dink with file descriptor while the standard I/O library has some input read from the kernel but not delivered to the application. (Similar problems could occur with outputs too.)Bergquist

© 2022 - 2024 — McMap. All rights reserved.