?
Solved

unix pipes

Posted on 2003-03-10
7
Medium Priority
?
364 Views
Last Modified: 2010-04-15
I am having a little bit of trouble getting pipes to work in linux...  I have a program (reader) that reads and writes to stdin and stdout.... I have another program that sets up 2 pipes then calls reader and sends strings to "reader" and then gets back a string from reader.  The program will read the string from a file, send it through the pipe to "reader" then get the string back and put it into another file... Here is what I have so far...

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


int main(int argc, char *argv[]) {

   int pfd[2],pfd2[2];
   int fd,fd2,x,y;
   pid_t childpid;
   char instring[256],buffer[256];

   fd=open("infile", O_RDONLY);
   fd2=open("outfile",O_WRONLY);

   x=pipe(pfd);
   y=pipe(pfd2);

   childpid=fork();

   if(childpid != 0) {
      close(pfd[0]);
      close(pfd2[1]);
      while(read(fd,instring,256)) {
         write(pfd[1],instring,strlen(instring));
         read(pfd2[0],buffer,sizeof(buffer));
      printf("%s\n",buffer);    //JUST CHECKING RESULTS FROM "READER"
      }
   } else {
      close(pfd[1]);
      close(pfd2[0]);
      close(0);
      dup(pfd[0]);
      close(1);
      dup(pfd2[1]);
      execlp("./reader","reader",NULL);
   }

   return 0;
}


I feel like it is close to working... but I can't get it to work... As it is now, it will open "reader" but then prints out 2 strange characters then quits.... You can see where I am just trying to printf the results it got back from "reader".  I have looked around the net for help on dup/fork/open/read/write but I havn't been able to find a good explination of how to do it all using files....

Thanks for any help.
0
Comment
Question by:coolguy81
[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
  • 5
7 Comments
 

Expert Comment

by:plushey
ID: 8110482
I'm not sure why you want the following two opens active for both child and parent:

fd=open("infile", O_RDONLY);
fd2=open("outfile",O_WRONLY);

I would have thought you'd need these just in the parent?

You have no error condition for the fork();

if (childpid > 0) { /* parent */
}
else if childpid == 0) { /* child */
}
else { /* error */
}

At present your parent part of the if will execute even if the fork(); failed.

Also check the return status of the read and write in the while loop, these should always be checked - you can't print the contents of buffer unless the read has succeeded.

HTH
0
 

Expert Comment

by:plushey
ID: 8110936
I'm not sure why you want the following two opens active for both child and parent:

fd=open("infile", O_RDONLY);
fd2=open("outfile",O_WRONLY);

I would have thought you'd need these just in the parent?

You have no error condition for the fork();

if (childpid > 0) { /* parent */
}
else if childpid == 0) { /* child */
}
else { /* error */
}

At present your parent part of the if will execute even if the fork(); failed.

Also check the return status of the read and write in the while loop, these should always be checked - you can't print the contents of buffer unless the read has succeeded.

HTH
0
 

Expert Comment

by:plushey
ID: 8111098
Sorry about the repeated post, I refreshed my browser window and was prompted to repost the data, I didn't think my post would be reposted and clicked Yes, doh!
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 5

Expert Comment

by:Kocil
ID: 8117164
Strange man ... why do you close the pipe before reading or writing ?

I think it should be easy like this.

int main(int argc, char *argv[]) {

  int pfd[2];  /* parent to child */
  int pfd2[2]; /* child to parent */
  int fd;      /* input for parent */
  int fd2;     /* output by parent */
  int x,y;
  int len;
  pid_t childpid;
  char instring[256],buffer[256];

  x=pipe(pfd);
  y=pipe(pfd2);

  childpid=fork();

  if(childpid > 0) { /* parent */
     fd=open("infile", O_RDONLY);
     while(len=read(fd,instring,256)) {
        write(pfd[1],instring,len);
     }
     close(fd);
     close(pfd[1]);

     /* wait back from the child */
     fd2=open("outfile", O_RDONLY);
     while(len=read(pfd2[0],instring,256) {
        write(fd2,instring,len);
     }
     close(fd2);
     close(pfd2[0]);
   } else {  /* child */
     while(len=read(pfd[0],buffer,256)) {
        write(pfd2[1],buffer,len);
     }
     close(pfd[0]);
     close(pfd2[1]);
  }
  return 0;
}
0
 

Accepted Solution

by:
plushey earned 500 total points
ID: 8118101
There are two pipes in this. The general rule is that you close the side of the pipe that you will not be using in both the child and the parent. So I have no problem with the two closes in either the child or parent of the code in the question, that all looks correct to me.
0
 

Author Comment

by:coolguy81
ID: 8123062
Plushey was right... I finally got it working and it turned out that there was no problem with the code.  The problem turned out to be with the calling program had a conflice with Debian... It worked fine when I compiled and tested it on a different OS... go figure.  

And yeah, I probley should of made the opens just available for the parent... and I should of checked for errors... but I didn't think that was what was causing it not to work... I was just in a hurry coding and didn't do much error checking....

anyway, thanks for the help.
0
 

Expert Comment

by:plushey
ID: 8124199
Thanks coolguy81,

Happy to have helped solve your problem, and to have gained my first points :-)
0

Featured Post

Technology Partners: 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

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
Examines three attack vectors, specifically, the different types of malware used in malicious attacks, web application attacks, and finally, network based attacks.  Concludes by examining the means of securing and protecting critical systems and inf…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.
Suggested Courses

764 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