Michael Latz
Michael Latz

Reputation: 101

printf visible after restoring closed stdout

My goal is to ignore the output to stdout and stderr in a region. Here is my code:

int stdOutCp = dup(STDOUT_FILENO);
int stdErrCp = dup(STDERR_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
printf("Works not\n");

dup2(stdOutCp, STDOUT_FILENO);
dup2(stdErrCp, STDERR_FILENO);
close(stdOutCp);
close(stdErrCp);
printf("This should be visible on the console\n");

If I skip the dup2 no output is redirected to the screen, but otherwise it is.

Upvotes: 0

Views: 749

Answers (1)

superjedi
superjedi

Reputation: 524

What do you mean by "ignoring" ?

If you'd like to have no more stdout,stderr you can just close them.

Though, if you don't have these file descriptors anymore (1 and 2) you may encounter -EBADF (Bad File Descriptor). So I'd suggest to open /dev/null after closing stdout/stderr, so that it gets directed to /dev/null, and nowhere else.

Of course, it should be the firsts open/close operations done by your program.

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>

int main(int argc, char **argv)
{
        fprintf (stdout, "test 0\n");
        fprintf (stderr, "test 1\n");

        close(1);
        close(2);

        /* Can be: assert(open("/dev/null", O_WRONLY) == 1); to control POSIX behavior. */
        open("/dev/null", O_WRONLY);
        /* Can be: assert(open("/dev/null", O_WRONLY) == 2); to control POSIX behavior. */
        open("/dev/null", O_WRONLY);

        fprintf (stdout, "test 2\n");
        fprintf (stderr, "test 3\n");

        return 0;
}

And if you just want to close stdout/stderr temporarily and not permanently you need to "save" a copy of stdout/stderr and keep following the same guidelines regarding /dev/null.

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>

int main(int argc, char **argv)
{
    /* Should display something */

    fprintf (stdout, "test 0\n");
    fprintf (stderr, "test 1\n");

    /* Saving filedescriptor 1 to filedescriptor 10 */
    dup2(1,10);
    /* Saving filedescriptor 2 to filedescriptor 20 */
    dup2(2,20);

    /* Should display something */
    fprintf (stdout, "test 2\n");
    fprintf (stderr, "test 3\n");

    close(1);
    close(2);

    setvbuf(stdout, NULL, _IONBF, 0);
    setvbuf(stderr, NULL, _IONBF, 0);

    /* Can be: assert(open("/dev/null", O_WRONLY) == 1); to control POSIX behavior. */
    open("/dev/null", O_WRONLY);
    /* Can be: assert(open("/dev/null", O_WRONLY) == 2); to control POSIX behavior. */
    open("/dev/null", O_WRONLY);

    /* Should not display anything */
    fprintf (stdout, "test 4\n");
    fprintf (stderr, "test 5\n");

    /* Restoring file descriptors */

    dup2(10,1);
    dup2(20,2);

    /* Should display something */
    fprintf (stdout, "test 6\n");
    fprintf (stderr, "test 7\n");

    return 0;
}

Upvotes: 1

Related Questions