[comp.unix.internals] Redirection of stderr

jik@athena.mit.edu (Jonathan I. Kamens) (03/15/91)

In article <574@dprmpt.UUCP>, larry@dprmpt.UUCP (Larry) writes:
|> In a C program, how can I change stderr from wherever it is directed
|> via the command line to a file, then later revert it back to it's 
|> original destination?

  This is not a comp.unix.wizards question.  I have cross-posted this response
to comp.unix.questions and directed followups there.

  First, "stderr_fd = dup(fileno(stderr))" to preserve the original stderr
output direction.  Then "fclose(stderr)", and immediately do "stderr =
fopen(your_stderr_file, "w")" (the "immediately" is so that the newly opened
file will get the same file descriptor stderr had, in case you've got that
file descriptor hard-coded somewhere in your code).  When you're done,
"fclose(stderr)" and do "stderr = fdopen(stderr_fd, "w")" to put things back
the way they were originally.

-- 
Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8085			      Home: 617-782-0710

bhoughto@pima.intel.com (Blair P. Houghton) (03/22/91)

In article <536@bria> uunet!bria!mike writes:
>In an article, torek@elf.ee.lbl.gov (Chris Torek) writes:
>>In article <524@bria> uunet!bria!mike writes:
>>>#define fdup2(A,B)	(memcpy(B,A,sizeof(FILE)))	/* UGLY */
>>Not only that, it does not work---because there is no guarantee that
>>a FILE object holds the state. [...]
>works just swimmingly for me, though! :-)

You're lucky, and probably don't close either of them, which
closes both of them, regardless of whether a FILE object holds
the state, because the kernel is now free to unlink the file.

				--Blair
				  "What I need is a real-time,
				   networked, 28 MIPS, tuna melt."

torek@elf.ee.lbl.gov (Chris Torek) (03/22/91)

>>In article <524@bria> uunet!bria!mike writes:
>>>#define fdup2(A,B)	(memcpy(B,A,sizeof(FILE)))	/* UGLY */

>In article <11127@dog.ee.lbl.gov> I wrote:
>>Not only that, it does not work---because there is no guarantee that
>>a FILE object holds the state. [...]

(Perhaps `does not' was too strong; but I wanted to scare people away....)

In article <536@bria> uunet!bria!mike writes:
>As I leap to my defense ...
>
>'Twould be true to state that it does not work for all implementations;
>works just swimmingly for me, though! :-)

Actually, it works under my stdio as well, and on most machines it is
sheer insanity to write one's stdio such that it will fail.  But it is
dangerous to assume that, because it works now, it will always work.
Code that uses an `fdup2' concept at all is probably best ported by
fixing the code, rather than making `fdup2' work.
-- 
In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427)
Berkeley, CA		Domain:	torek@ee.lbl.gov

zink@panix.uucp (David Zink) (03/29/91)

In article <3181@inews.intel.com>, bhoughto@pima.intel.com,
           (Blair P. Houghton) sez:
 ( About using memcpy to duplicate FILEs )
>You're lucky, and probably don't close either of them, which
>closes both of them, regardless of whether a FILE object holds
>the state, because the kernel is now free to unlink the file.
(Given NFS, the kernal is _always_ free to unlink the file.)
>
>                               --Blair

I thought more fun was to close one and then open another file . . . .
   if ((fp = fopen("logfile", "a+")) != (FILE *)0)
   {
        setbuf(fp, (char *)0);
        memcpy((char *)stderr, (char *)fp, sizeof(*fp));
        fclose(fp);
   }
   if ((fp = fopen("database", "r+")) == (FILE *)0)
   {
        perror("database");/* May even succeed if it writes to fd 2 directly */
        exit(1);/*NOTREACHED*/
   }
   fprintf(stderr, "Beginning operations\n");
   . . .

Looks good to me!
      David
/*{fflush(a);close(fileno(a));fileno(a)=dup(fileno(b));} Works some places.*/
. . . if you must . . .