Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

duplicating stdout to a file as well

Posted on 2000-04-12
10
Medium Priority
?
385 Views
Last Modified: 2010-04-02
I'm writing my own shell, and need to be able to duplicate my output to stdout and a file at the same time for a forked process which then calls execve.  To just change stdout to a file I know you do:
dup2(outf,1);
where outf is the open file.  I'm not sure how to make it do both though...  I tried:
tempf = dup(1);
dup2(outf,tempf);
to no avail.

Please help me shed light on this.
Thanks,
Josh
0
Comment
Question by:jbirk
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
10 Comments
 
LVL 1

Expert Comment

by:940961sl
ID: 2710686
The best way is to write your own logging functions :

void startlog()
{
   //open file with handle LogFile here
}

void stoplog()
{
   //close file with handle LogFile here
}

void vlog(const char *format, va_list args)
{
   vprintf(format, args); //to stdout
   vfprintf(LogFile, format, args); //to file
}

void log(const char *format, ...)
{
   va_list args;

   va_start(args, format);
   vlog(format, args);
   va_end(args);
}

and now use log or vlog instead of printf and vprintf to write to stdout and a file at the same time.
0
 
LVL 8

Author Comment

by:jbirk
ID: 2711770
Sorry, that's not possible.  I said it's a shell.  I have no control over what command is used.  I'm using execve to run a completely seperate program, like ls,more,diff,etc...

I suppose if I had to, I could open up the file that was written to, read the data, and write it out again to stdout after the program is done, but that's not really satisfactory either because the programs could be interactive, and the user will need to see the output right away so they know what's going on.

There must be some way to duplicate the output!?

-Josh
0
 
LVL 1

Expert Comment

by:LordDragon
ID: 2712139
Assuming UNIX ...

Open a pipe, set that up as the stdout of the process, read the pipe and then copy it to stdout and the file at the same time.

leaving out error checking ...

int fd[2];

pipe(fd);
switch (fork()) {
case 0:   /* in child */
   dup(fd[0], 1);
/* start child */
   break;
default:  /* in parent */
   while (read(fd[1], &ch, 1) > 0) {
      /* write to log file */
      write(1, &ch, 1);
   }
   break;
}
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 3

Expert Comment

by:Laminamia063099
ID: 2712146
Look into how some UNIX shells allow for you to enter the command:
   script somefilename
This command copies all output to the file somefilename while at the same time outputting the stdout.  This might be the answer already solved for you.

Laminamia
0
 
LVL 8

Author Comment

by:jbirk
ID: 2712872
LordDragon (nice username BTW), how will the parent process know when the child process is done?  Does fd[1] report a different character or something?  I'm using a waitpid command now so it pauses until the child returns.

And yes, you are close to right, I'm using Linux, though it should function the same.

I had hoped this would be a simple solution...  but from the look of things thus far it isn't...  Do I have to use a pipe?  And won't that pipe also just redirect the stdout so it's still not going to the screen?  I guess I'd have to write to the file AND stdout in the parent, won't I?


Laminamia, you're logic is why I assumed it would be some system call I just didn't know.  Since other shells do it, it should be simple, right?  Unfortunately, I won't have the luxury of asking a parent shell or using "system()" to do the work for me since this'll be running in a restricted environment, so I have to figure out how they did it...

Thanks everyone for your help thus far:)
-Josh

0
 
LVL 1

Accepted Solution

by:
LordDragon earned 200 total points
ID: 2713447
I wasn't sure how you wanted to write to the log file, so I just put:

/* write to log file */

where you ned to write to the log file...


Also, when the child application exits, the os will close the stdout for the child and you will get an eof on the pipe (you may have to add:

close(fd[0]);

right in the beginning of the default case in the switch, tho'.)

Anyway, that will work.  You still need to waitpid for the child to exit or you will be creating zombie processes...

0
 
LVL 8

Author Comment

by:jbirk
ID: 2713741
Adjusted points from 40 to 50
0
 
LVL 8

Author Comment

by:jbirk
ID: 2713742
So this loop:
while (read(fd[1], &ch, 1) > 0) {
                                        /* write to log file */
                                        write(1, &ch, 1);
                                     }
will exit when I get that eof?  Then after the while I should put the waitpid() even though I know the process will already have finished?

Thanks for your help,
-Josh
0
 
LVL 8

Author Comment

by:jbirk
ID: 2729213
OK, what do you think about using the shell program tee?  I could launch it, launch the subprogram, and have a pipe setup between them.  This way tee should handle the splitting for me, right?

I'm going to give that a try first, since it sounds like it might be simpler.

-Josh
0
 
LVL 8

Author Comment

by:jbirk
ID: 2742268
My thesis advisor wants me to use your solution.  Thanks for the help!  I'll figure it out from here.

-Josh
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.

598 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question