Thread: pipe

  1. #1
    Registered User
    Join Date
    Mar 2013
    Posts
    20

    pipe

    Hello, so im trying to make a pipe that use child and parent for reading/writing.

    I have a textfile which i get from the argument argv[1], the parent reads and send every character in the file to the pipe and the child counts the letters from the pipe and prints it.

    Is the code in the parent part how I write to a pipe?
    Why does my textfile just get appended two times with the already existing text in the file if I do this?


    Code:
    main(int argc, char* argv[])
    {
      int index = 0, fd[2], pid, i;
      char buffer[1024];
    
    
      if(argc != 2)
      {
        printf("Usage: program <filname>\n");
        exit(0);
      }
    
    
      //pipe
      if(pipe(fd) == -1)
    
    
      {
        perror("pipe");
        exit(EXIT_FAILURE);
      }
    
    
      //fork
      if((pid = fork()) == -1)
      {
        perror("fork");
        exit(EXIT_FAILURE);
      }
    
    
      if(pid == 0)
      {
        int letterCounter = 0;
        close(fd[1]); //close unused write end
    
    
        //read letters from the pipe
        while(read(fd[0], &buffer, sizeof(buffer)) > 0)
        {
          for(i = 0 ; i < sizeof(buffer) ; i++)
          {
            if(isalpha(buffer[i]))
            {
              letterCounter++;
              printf("%c", buffer[i]);
            }
          }
        }
    
        printf("\n\nChild counting letters: %d\n", letterCounter);
    
        close(fd[0]); //close finished read end
        _exit(EXIT_SUCCESS);
      }
      else //parent
      {
        close(fd[0]); //close unused read end
    
    
        printf("\nParent writing to pipe:\n");
    
    
        write(fd[1], &buffer, sizeof(buffer));
    
    
        close(fd[1]); //close finished write end
        wait(NULL); //wait for child to finish, avoid zombies
        exit(EXIT_SUCCESS);
      }
    }

    The output looks like this:

    Parent writing to pipe:
    rDBppXbLTPpqPpqPpEnxPdhXiixlTTHhTpHpNXqmkoXNrXpINA L


    Child counting letters: 51
    but the text in the file is "this is a textfile 12345"

    Can someone see what I am missing?14
    Last edited by Gatsu; 03-14-2013 at 11:17 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Where exactly do you read from the file, read it into the buffer in the parent?

    At the moment, you just write garbage down the pipe.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Mar 2013
    Posts
    20
    adding like this?

    fd[0] = open(argv[1], O_RDWR);
    fd[1] = open(argv[1], O_RDWR);

    it gave me:

    thisisatextfileDBppEbPEPpPpPDpnExGBBPDEBxLRFhXsTiiHhTDHNXqoXNXpIN


    Child counting letters: 65


    Parent writing to pipe:

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Here, let me make it simpler.

    Go back to your original program, and just change this
    Code:
      char buffer[1024] = { "I should have read something from the file, but I didn't" };
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Mar 2013
    Posts
    20
    So, to write whats in the file to the pipe I have to make a FILE and use fopen and maybe fscan to stuff the file contents in another array that I can send to the pipe?

    I would like if there is something simpler.

    I think now I'm trying to send contents of an array thats empty to the pipe and write that to the same array

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Well if you want a pipe, then you're going to have to do some reading and writing yourself.

    Sure, you could make the child read directly from the file, but what would be the point of the pipe?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Mar 2013
    Posts
    20
    So I create the FILE:
    Code:
    FILE *fp = fopen(argv[1], "r");
    And another array for it:
    Code:
    char fileA[1024];
    Make a loop to read all characters in it:
    Code:
    for(i = 0 ; i < sizeof(fileA) ; i++)
    {
        fscanf(fp, "%c", &fileA[i]);
    }
    And write it to the pipe:
    Code:
    write(fd[1], &fileA, sizeof(buffer));
    But I still get the correct text along with bla bla text like this:

    thisisatextfileXoTXEuhXpThhpXplXlBQJKlZfkmpTyppfELFhDCrrrTtttPiiH phXHXpX


    Child counting letters: 72
    Shouldnt I be able to use the file descriptor to make this work? Isnt it pointing at the file? But I didnt anywhere tell the fd that it should contain my textfile.. gah it dont make sense. Does fd[0] and fd[1] magically contain the descriptor for my textfile which name is in argv[1]??
    Last edited by Gatsu; 03-14-2013 at 02:12 PM.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    I don't know, perhaps you should post the whole program, so we can see the context.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Mar 2013
    Posts
    20
    there is only one method, the main method and its in first post, its whole program, I just left out the includes

  10. #10
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Quote Originally Posted by Gatsu View Post
    And another array for it:
    Code:
    char fileA[1024];
    Make a loop to read all characters in it:
    Code:
    for(i = 0 ; i < sizeof(fileA) ; i++)
    {
        fscanf(fp, "%c", &fileA[i]);
    }
    And write it to the pipe:
    Code:
    write(fd[1], &fileA, sizeof(buffer));
    I guess your file doesn't have 1024 characters in it. Thus you are still printing garbage when you send the whole array.
    You should stop reading the file after you encounter EOF. Check the return value of fscanf(). And then only send the part of the array which contains valid text.

    Bye, Andreas

  11. #11
    Registered User
    Join Date
    Mar 2013
    Posts
    20
    Ok thanks all I did a bit more googling and I came up with this:

    the parent does this (read file to array and send to pipe):

    Code:
    char file[1024];
        FILE *fp = fopen(argv[1], "r");
        int q;
        int number = 0;
    
    
        while((q = fgetc(fp)) != EOF)
        {
          file[number] = q;
          printf("%d %c\n", number, file[number]);
          number++;
        }
    
    
        write(fd[1], file, sizeof(file));
    this adds all characters from the textfile successfully in the fileBuffer like this:
    0 a
    1
    2 t
    3 e
    4 x
    5 t
    6 f
    7 i
    8 l
    9 e
    10
    11 1
    12 2
    13 3
    14 4
    15 5
    16
    17 %
    18 &
    19 #
    20 /
    21 (
    22 )
    23
    but when the child prints it, it looks like this:
    SSRpDBVpSRTRRPTbTTpOStPpPpPpepdTnxPOPPTQlTTTFhXPVi iTtHhTTUHUNXqoXPNVVPVXVVpVpIZNaVV
    How come the pipe screws my letters?
    Last edited by Gatsu; 03-15-2013 at 08:35 AM.

  12. #12
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Code:
    write(fd[1], file, sizeof(file));
    You still don't get it. What is the value of sizeof(file)? If you don't know it, then print it (or even better use a debugger to check the values of expressions during run time).
    You could also check the return value of write() which tells you how many bytes were written.

    Generally, you should post a small but compilable program which we can run and which demonstrates your problem. For your problem it is also important to know how you are reading the pipe.

    Bye, Andreas

  13. #13
    Registered User
    Join Date
    Mar 2013
    Posts
    20
    I replaced sizeof(file) with number which is the amount of characters in the textfile and check what write returns:
    write return: 25
    apTp


    Child counting letters: 4
    You may see the full code here:

    [C] #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <sy - Pastebin.com

    You send a textfile like "file.txt" as argument when running this program and in this textfile some text, place it in same folder.

    Just copy, paste and compile if you want. Thank you for your time! I really want to get it
    Last edited by Gatsu; 03-15-2013 at 12:28 PM.

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Code:
        while(read(fd[0], pipeBuffer, 1) > 0)
        {
          if(isalpha(pipeBuffer[counter]))
    You're always reading into the same character, but you examine some ever increasing subscript.

    Setting your print string to this will be informative
    printf("\n\nChild counting Alpha letters: %d, total letters: %d\n\n", letterCounter,counter);
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  15. #15
    Registered User
    Join Date
    Mar 2013
    Posts
    20
    while(read(fd[0], &pipeBuffer[counter], 1) > 0)

    boooya!!

    thanks so much!!!! ^^

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pipe multiple programs using pipe() and c
    By HaitiBoy in forum C Programming
    Replies: 1
    Last Post: 12-07-2010, 05:19 PM
  2. pipe
    By vapanchamukhi in forum C Programming
    Replies: 2
    Last Post: 09-23-2008, 01:35 AM
  3. Pipe
    By quickNitin in forum C Programming
    Replies: 4
    Last Post: 09-06-2006, 03:04 AM
  4. Pipe problem, popen(), pipe().
    By apacz in forum C Programming
    Replies: 7
    Last Post: 06-08-2006, 12:55 AM
  5. pipe()
    By bojan in forum C Programming
    Replies: 2
    Last Post: 04-13-2006, 07:47 AM