pagratios
pagratios

Reputation: 394

Redirect stdout with pipes and fork in C

I have an exercise about ptrace and pipes. The following code is a part from whole program. Pipes are made before main part and this_trace.s_out is 1. Main father create child and this child makes his own child for stdout. When program runs ls then it is print on screen and doesn't write in file. What is wrong?

if(pid == 0)
{
char buf0[BUFFSIZE], buf1[BUFFSIZE], buf2[BUFFSIZE];
int length0, length1, length2;


if(this_trace.s_out == 1)   //For stdout redirection
{
    if((pid1=fork()) == -1)
    {
        perror("fork");
        exit(1); 
    }

    if(pid1 == 0) //child for stdout redirect
    {//sleep(2);
        if(fd1 = open(this_trace.out_name,O_WRONLY | O_CREAT | O_TRUNC, 0666) == -1)
        {
            perror("create stdout file");
            exit(1);
        }


        close(p_out[WRITE]);
        close(p_in[READ]);
        close(p_in[WRITE]);
        close(p_err[READ]);
        close(p_err[WRITE]);

        do{
            if((length1 = read(p_out[READ],buf1,BUFFSIZE)) == -1)
            {
                perror("Read for stdout redirection");
                exit(1);
            }
            write(fd1, buf1, length1);
        }while(length1 > 0);


        close(fd1);
        //close(p_out[READ]);
        return 0;
        //break;

    }
    else if(pid1 > 0)//child from main father
    {
        close(p_out[READ]);
        close(p_in[READ]);
        close(p_in[WRITE]);
        close(p_err[READ]);
        close(p_err[WRITE]);

        dup2(p_out[WRITE], 1);
    }

}




ptrace(PTRACE_TRACEME, 0, NULL, NULL);  


//execv(argv[1],NULL);
execl("/bin/ls","ls",NULL);


}

Sorry for my bad English.

Upvotes: 0

Views: 1073

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 753475

It is not clear why you have so many processes. You have a problem at:

if (fd1 = open(this_trace.out_name,O_WRONLY | O_CREAT | O_TRUNC, 0666) == -1)

This assigns 0 or 1 to fd1, regardless of the file descriptor opened. It should be:

if ((fd1 = open(this_trace.out_name,O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1)

After you use dup2() (or dup()) to redirect a file descriptor to a standard channel, you should close the original file descriptor. Thus, after dup2(p_out[WRITE], 1); you need close(p_out[WRITE]);.

You should detect failure from execl() and deal with it; if the execl() returns, it failed.

You show unused variables buf0 and buf2 (and corresponding length0 and length2).

Upvotes: 1

Related Questions