-1
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>


int main(void) {


    if(mkfifo("fifo", S_IRWXU) < 0 && errno != EEXIST) {
        perror("Fifo error");
        exit(EXIT_FAILURE);
    }

    pid_t pid = fork();

    if(pid == 0) /*dziecko*/
    {
        int fifo_write_end = open("fifo", O_WRONLY);

        if(fifo_write_end < 0)
        {
            perror("fifo_write_end error");
            exit(EXIT_FAILURE);
        }

        if(dup2(fifo_write_end, STDOUT_FILENO) < 0)
        {
            perror("dup2 fifo_write_end error");
            exit(EXIT_FAILURE);
        }

        if(execlp("/bin/ls", "ls", "-al", NULL) < 0)
        {
            perror("execlp error");
            exit(EXIT_FAILURE);
        }

    }


    if(pid > 0) /*rodzic*/
    {
        int fifo_read_end = open("fifo", O_RDONLY);

        if(fifo_read_end < 0)
        {
            perror("fifo_read_end error");
            exit(EXIT_FAILURE);
        }
        if(dup2(fifo_read_end, STDOUT_FILENO) < 0)
        {
            perror("dup2 fifo_read_end error");
            exit(EXIT_FAILURE);
        }

        int atxt = open("a.txt", O_WRONLY|O_CREAT, S_IRWXU);

        if(atxt < 0)
        {
            perror("a.txt open error");
            exit(EXIT_FAILURE);
        }

        if(dup2(atxt,STDOUT_FILENO) < 0)
        {
            perror("dup2 atxt error");
            exit(EXIT_FAILURE);
        }

        if(execlp("/usr/bin/tr", "tr", "a-z", "A-Z", NULL) < 0)
        {
            perror("tr exec error");
            exit(EXIT_FAILURE);
        }

    }

    if(pid < 0)
    {
        perror("Fork error");
        exit(EXIT_FAILURE);
    }


    return 0;
}

Program doesn't stop . I have no idea why . It should execute ls -al | tr a-z A-Z and write it in file a.txt.

And if someone can , please explain me how to do ls-al | tr a-z A-Z | tr A-Z a-z > a.txt . For another tr I need second mkfifo right ? I'm not sure how it's working and if should i close write or read descriptor here . With "pipe" it was nesesery.

Thanks for any help !

Gwiazdek
  • 149
  • 1
  • 8

1 Answers1

1

The read end of the pipe won't report EOF until the pipe is closed. And a pipe isn't closed until all the descriptors that refer to it are closed. After you call dup2, the pipe is referenced by both the original FD and the descriptor that you duped it to. You need to close the original FD.

    if(dup2(fifo_write_end, STDOUT_FILENO) < 0)
    {
        perror("dup2 fifo_write_end error");
        exit(EXIT_FAILURE);
    }
    close(fifo_write_end);
    if(execlp("/bin/ls", "ls", "-al", NULL) < 0)
    {
        perror("execlp error");
        exit(EXIT_FAILURE);
    }

Another problem is that the process running tr needs to dup the FIFO to stdin, not stdout. So

    if(dup2(fifo_read_end, STDOUT_FILENO) < 0)
    {
        perror("dup2 fifo_read_end error");
        exit(EXIT_FAILURE);
    }

should be

    if(dup2(fifo_read_end, STDIN_FILENO) < 0)
    {
        perror("dup2 fifo_read_end error");
        exit(EXIT_FAILURE);
    }
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Thanks , it works after close read , but what with second TR . I need second mkfifo? – Gwiazdek Apr 11 '16 at 21:28
  • 1
    Yes, you need a FIFO for each pipe. BTW, why are you using FIFOs instead of calling `pipe()`? – Barmar Apr 11 '16 at 21:39
  • It's a task in my studies. To be clear , where should be second fifo ? There will be 2 forks , first like up and second in child to make "grandchild " right ? – Gwiazdek Apr 11 '16 at 21:42
  • So there sould be , ls in grandchild , first tr in child , and second tr in parent , but should I make secound mkfifo after child but before parent ? – Gwiazdek Apr 11 '16 at 21:48
  • It doesn't really matter where you create the second FIFO. – Barmar Apr 11 '16 at 21:50
  • Damn , it checked wrong code , you tip's don't work :/ http://wklej.org/id/2270276/ it's still doesn't work – Gwiazdek Apr 11 '16 at 21:54
  • Thanks a lot ! Can you help me with second tr ? Closing it doesn't mater here , there was stupid mistike , OUT instead of IN like You said. – Gwiazdek Apr 11 '16 at 22:47