Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

unix pipes

Posted on 2003-03-10
7
Medium Priority
?
369 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
  • 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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
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

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.
Suggested Courses

564 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