[comp.unix.questions] Redirecting stdout and stderr

jdt@voodoo.UUCP (Jim Tomlinson) (12/20/89)

Sorry to ask a question that's no doubt been answered a bazillion
times, but the subject lines for last month suggest the answer hasn't
come across recently.  I'm trying to redirect stdout and stderr to a
file; we'll skip why I don't just do this from the shell; suffice to
say that the program is called by inetd, not to mention I'm detaching
the process from any controlling terminal, parent process group, etc.
To cut to the chase: we know stderr is unbuffered and stdout is
buffered.  The following code segment should unbuffer stdout, or at
least flush stdout before we fprintf "and to stderr":

#include <stdio.h>
main()
{
    FILE	*pr_file;
    
    /* close stdout and stderr */
    close(1);
    close(2);

    /* now let's point stdout and stderr at our logfile */
    if (pr_file = fopen("/tmp/testlog", "w"))
    {
	/* we got stdout (next avail. file descriptor); let's dup to
	 * point stderr at it */
	dup(1);
	/* specify unbuffered output */
	if (setvbuf(pr_file, (char *) NULL, _IONBF, 0))
	{
	    perror("setvbuff failed");
	    exit(-1);
	}
	fprintf(stdout, "Printing to stdout\n");
	fflush(pr_file);
	fprintf(stderr, "and to stderr.\n");

    }
    else
    {
	exit(-1);
    }
}

but /tmp/testlog looks like this after the code is run:

and to stderr.
Printing to stdout

Why isn't the output in the proper order?  BTW, this is SGI's
IRIX 3.2 (SYSV with BSD extensions).  Thanx for any help you
can give me on this.


Jim Tomlinson                                                  (206) 234-7741
BoGART Project                               ....uw-beaver!ssc-vax!voodoo!jdt
Boeing Computer Services, Renton, WA           "falling snow, excellent snow"

cpcahil@virtech.uucp (Conor P. Cahill) (12/21/89)

In article <635@voodoo.UUCP>, jdt@voodoo.UUCP (Jim Tomlinson) writes:
> To cut to the chase: we know stderr is unbuffered and stdout is
> buffered.  The following code segment should unbuffer stdout, or at
> least flush stdout before we fprintf "and to stderr":

 	[ example of tryint to redirect stdout/stderr deleted ]

> but /tmp/testlog looks like this after the code is run:
> 
> and to stderr.
> Printing to stdout
> 
> Why isn't the output in the proper order?  BTW, this is SGI's
> IRIX 3.2 (SYSV with BSD extensions).  Thanx for any help you
> can give me on this.

Because you are flushing a different stdio buffer.  Why don't you 
do something like the following:

#include <stdio.h>
#include <fcntl.h>
main()
{
	int	pd;
    
	close(1);
	close(2);

	pd = open("/tmp/xxx",O_CREAT|O_WRONLY,0666);
	/* I know, we need to check opens return */
	dup(pd);

	/* specify unbuffered output */
	if (setvbuf(stdout, (char *) NULL, _IONBF, 0))
	{
	    perror("setvbuff failed");
	    exit(-1);
	}
	fprintf(stdout, "Printing to stdout\n");
	fflush(stdout);
	fprintf(stderr, "and to stderr.\n");
}


-- 
+-----------------------------------------------------------------------+
| Conor P. Cahill     uunet!virtech!cpcahil      	703-430-9247	!
| Virtual Technologies Inc.,    P. O. Box 876,   Sterling, VA 22170     |
+-----------------------------------------------------------------------+