John U
John U

Reputation: 2993

Redirect stdout/stderr using dup2, then resinstate later

Background: We have an embedded linux system running Busybox (limited resources), we have a process running which normally spits out lots of info on the console (via stdout / stderr) but we'd like to temporarily redirect it to syslog (using syslogd / logger) on command - WITHOUT restarting the process or rebooting.

Using the code found here works nicely, until we try to stop/close the logger fd at which point writes to stdout/stderr fail and everything breaks. Example below:

int main()
{

    // Got command to direct all output to syslog:

    FILE *fl;
    fl = popen("logger","w");
    if(fl == NULL)
        return 1;
    fprintf(fl,"logger test new"); // This goes to syslogd
    int nf;
    nf = fileno(fl);
    dup2(nf,STDOUT_FILENO);
    dup2(nf,STDERR_FILENO);
    fprintf(stdout,"Written in stdout\n");
    fprintf(stderr,"Written in stderr\n");

    // ...some time later when we've logged enough things:

    pclose(fl);
    fprintf(stdout,"This will fail\n");
    fprintf(stderr,"Catch fire and die\n");
}

So the question is, (how)can we restore the original state once we're done with the logging?

Having RTFM on dup() and dup2() I'm not clear on how exactly we can achieve this, if it's possible to "reopen" perhaps freopen() stdout/stderr, but as a last resort it would be acceptable to perhaps point nf to /dev/null/ so things at least don't crash.

Upvotes: 4

Views: 8191

Answers (2)

Nibal
Nibal

Reputation: 9

Linux man pages are clear that dup2 doesn't close the oldfd. Don't forget to also close nf.

Upvotes: 0

spectras
spectras

Reputation: 13542

You must dup the initial file descriptors before your dup2, otherwise dup2 closes them and there is no way to recover them.

int stdout_copy = dup(STDOUT_FILENO);
dup2(nf, STDOUT_FILENO);

/* do something with stdout */

dup2(stdout_copy, STDOUT_FILENO);
close(stdout_copy);

Throw in error handling, add fflush calls to ensure you don't leave data unwritten in stdlib buffers and you should be good.

Upvotes: 6

Related Questions