Reputation: 83
I have a task to make both stderr and stdout to print to a file called "log.out". I"m not allowed to delete code lines, only to add them. The stdout part was easy, I have just added close(1); and now it is working. But I have already spend a couple for hours trying to learn how to use the whole dup/dup1/dup2 technic but I"m just not able to make it work even after reading a lot about the subject in the internet. It would be really nice if someone will show me what lines of code I need to add to make it work, and explain me how it works. Thanks!
#include<stdio.h>
#include<stdlib.h>
#include <unistd.h> // for fork, sleep etc.
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
void fork_son(char*, int);
void do_son();
int open_file(char*);
int
main()
{
fork_son("1st", 0);
fork_son("2nd", 1);
exit(0);
}
void fork_son(char* which, int need_file)
{
int pid;
int status;
if (need_file)
{
close(1); //close stdout
open_file("log.out");
}
// close and open files before forking
pid = fork();
if (pid <0)
{
fprintf(stderr,"process %d, Fork Failed... Exiting\n", getpid());
exit(1);
}
if (pid == 0)
do_son(which);
else
{
printf("waiting for %s son...", which);
wait(&status);
printf("%s son exited!\n", which);
}
return;
}
void do_son(char* which)
{
fprintf(stdout,"Hello from %s son!\n", which);
fprintf(stderr,"%s son: I'm going to exit\n", which);
exit(0);
}
int open_file(char* name)
{
int fd;
fd = open(name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
// check if open succeeded
if (fd <0)
{
fprintf(stderr, "ERROR: open \"%s\" failed (%d). Exiting\n", name, fd);
exit(2);
}
// if (fd != 1)
// {
// fprintf(stderr,"ERROR: open \"%s\" - fd is %d (expected 1). Exiting\n", name, fd);
// exit(3);
// }
printf("opened file %s, file descriptor is: %d\n",name, fd);
return(fd);
}
Upvotes: 3
Views: 1112
Reputation: 14866
The way open works, it searches for free entry in file descriptor table. Where entries 0, 1 and 2 are reserved for stdin
, stdout
and stderr
respectively.
stdin - 0
stdout - 1
stderr - 2
If you want to redirect stdout
and stderr
to log.out
you could simply do the following:
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
int main()
{
int fd = - 1;
fd = open("log.out", O_RDWR | O_CREAT);
dup2(fd, 1); // redirects stdout to log.out
dup2(fd, 2); // redirects stderr to log.out
/* Print to stderr and to stdout */
fprintf(stdout, "%s", "Hello world\n");
fprintf(stderr, "%s", "Stack overflow!\n");
return 0;
}
If you care about order, a call to fflush should follow fprintf as redirecting stdout to a file will not flush buffer on newlines.
Upvotes: 3