redirecting standard output in c then resetting standard output
Asked Answered
B

3

7

I'm trying to use redirects in C to redirect input to one file and then set standard output back to print to the screen. Could someone tell me what's wrong with this code?

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char** argv) {
    //create file "test" if it doesn't exist and open for writing setting permissions to 777
    int file = open("test", O_CREAT | O_WRONLY, 0777);
    //create another file handle for output
    int current_out = dup(1);

    printf("this will be printed to the screen\n");

    if(dup2(file, 1) < 0) {
        fprintf(stderr, "couldn't redirect output\n");
        return 1;
    }

    printf("this will be printed to the file\n");

    if(dup2(current_out, file) < 0) {
        fprintf(stderr, "couldn't reset output\n");
        return 1;
    }

    printf("and this will be printed to the screen again\n");

    return 0;
}
Brogle answered 24/7, 2011 at 7:50 Comment(1)
There is a completely different way to solve this same problem here: #585368.Happ
V
3

Your second dup2 call is wrong, replace with:

if (dup2(current_out, 1) < 0) {
Vinasse answered 24/7, 2011 at 7:57 Comment(0)
B
4

One thing you'll have to make sure to do before that will work at all, is to call fflush(stdout); before switching the stdout file descriptor out from under it. What's probably happening is that the C standard library is buffering your output, unaware that you're shifting around the file descriptors underneath it. The data you write using printf() isn't actually sent to the underlying file descriptor until its buffer becomes full (or your program returns from main).

Insert the call like this:

    fflush(stdout);
    if(dup2(file, 1) < 0) {

before both calls to dup2().

Brotherhood answered 24/7, 2011 at 7:54 Comment(2)
I don't think this was OP's problem here, but it's very good advice and should almost always be followed whenever you mix stdio with file descriptor io.Yugoslavia
That's true, I actually didn't notice the incorrect file descriptor at first until somebody else mentioned it. When writing to a terminal, stdio output will probably be line buffered, so the code without fflush() is likely to work until the OP tries redirecting stdout to a file.Brotherhood
V
3

Your second dup2 call is wrong, replace with:

if (dup2(current_out, 1) < 0) {
Vinasse answered 24/7, 2011 at 7:57 Comment(0)
A
1

Just replace dup2(current_out, file) with dup2(current_out, 1), and things should work better.

Anderegg answered 24/7, 2011 at 7:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.