[comp.os.msdos.programmer] Redirecting stdout via dup2

waynet@kit.tek.com (Wayne Turner) (03/22/91)

I have an application where I want to redirect stdout to a file under
program control (not from the command line). I'm using dup and dup2 to
achieve this and it works with the exception that I can't *undo* the
redirection within the program (however, exiting to command.com *does* 
result in undoing the redirection).

The following code fragment shows what I'm doing; each comment line shows
the intent and result of the line it precedes.

    /* dup stdout and redirect it to temp.fil */
    oldout = dup(1); 
    newout = open("temp.fil", O_WRONLY|O_CREAT, 0777);
    dup2(newout, 1);
    /* write to 1 -- output redirected to temp.fil */
    write(1, temp_file_string, strlen(temp_file_string));
    /* write to dup'd stdout -- output goes to console */
    write(oldout, stdout_string1, strlen(stdout_string1));
    /* undo redirection on stdout */
    dup2(1, oldout);
    /* string2 should go to console but goes to temp.fil instead */
    write(1, stdout_string2, strlen(stdout_string2));

I've tried the same with direct DOS calls (INT 21 Function 45H (dup)
and INT 21 Function 46H (dup2)) but get the same results.  I've
tried many combinations of close()'ing handles before and after the
second dup2 but none gives the desired effect. (BTW, I'm using DOS 3.31)

Any ideas/solutions welcome.

Thanks,
Wayne Turner
Tektronix, Inc.
Redmond, Oregon
waynet@kit.CNA.TEK.COM

tmilner@hprpcd.rose.hp.com (tom milner) (04/04/91)

> I have an application where I want to redirect stdout to a file under
> program control (not from the command line). I'm using dup and dup2 to
> achieve this and it works with the exception that I can't *undo* the
> redirection within the program (however, exiting to command.com *does* 
> result in undoing the redirection).
> 
> The following code fragment shows what I'm doing; each comment line shows
> the intent and result of the line it precedes.
> 
>     /* dup stdout and redirect it to temp.fil */
>     oldout = dup(1); 
>     newout = open("temp.fil", O_WRONLY|O_CREAT, 0777);
>     dup2(newout, 1);
>     /* write to 1 -- output redirected to temp.fil */
>     write(1, temp_file_string, strlen(temp_file_string));
>     /* write to dup'd stdout -- output goes to console */
>     write(oldout, stdout_string1, strlen(stdout_string1));
>     /* undo redirection on stdout */
>     dup2(1, oldout);
>     /* string2 should go to console but goes to temp.fil instead */
>     write(1, stdout_string2, strlen(stdout_string2));
> 
> I've tried the same with direct DOS calls (INT 21 Function 45H (dup)
> and INT 21 Function 46H (dup2)) but get the same results.  I've
> tried many combinations of close()'ing handles before and after the
> second dup2 but none gives the desired effect. (BTW, I'm using DOS 3.31)
> 
> Any ideas/solutions welcome.
> 
> Thanks,
> Wayne Turner
> Tektronix, Inc.
> Redmond, Oregon
> waynet@kit.CNA.TEK.COM

You were real close (but no cigar). The line after "undo redirection to stdout"
should read:

        dup2(oldout, 1);

And that will do it.

-Tom.