简体   繁体   中英

Undo redirect of stdout with dup2

The following code is writing both "A" and "B" to the file "out.txt", with the first call to open returning 3 and second call returning 4.

What I expected is for "A" to be written to the file and "B" to be written to the screen. I also expected open to return 3 in each case.

What should I do to fix the code below:

int main(int argc, char** argv)
{
    int file = open("out.txt", O_APPEND | O_WRONLY);
    if(file != 3)    return 1;

    if(dup2(file,1) < 0)    return 1;
    std::cout << "A" << std::endl;

    if(dup2(1,file) < 0)    return 1;
    std::cout << "B" << std::endl;

    file = open("out.txt", O_APPEND | O_WRONLY);
    if(file != 3)    return 1;

    return 0;
}

Commenting from this link ;

if(dup2(file,1) < 0)    return 1;

makes newfd be the copy of oldfd, closing newfd first if necessary`

that is, it closes stdout and makes file descriptor 1 a clone of file descriptor 3.

if(dup2(1,file) < 0)    return 1;

If oldfd is a valid file descriptor, and newfd has the same value as oldfd, then dup2() does nothing, and returns newfd.

So it does nothing since file descriptor 1 has the same value as file descriptor 3.

file = open("out.txt", O_APPEND | O_WRONLY);

will open a file with the next available file descriptor. Since file descriptor 3 is busy, it will (in this case) use 4.

What you want to do is something more along the lines of;

int stdoutCopy = dup(1);                // Clone stdout to a new descriptor
if(dup2(file, 1) < 0) return 1;         // Change stdout to file
close(file);                            // stdout is still valid
std::cout << "A" << std::endl;
if(dup2(stdoutCopy,1) < 0) return 1;    // Change stdout back from the clone
close(stdoutCopy);                      // Close the clone
std::cout << "B" << std::endl;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM