[SOLVED] Problems with FIFO pipe using a child and parent process
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Problems with FIFO pipe using a child and parent process
Hi,
I am trying to write a simple program where my parent writes a small message like "hello" to the child. So the parent writes and the child reads. When I run, I get 'child read from fifo failed: resource temporarily unavailable.'
Can someone look at my code and tell me whats wrong or missing? I cant seem to figure it out.
It seems like what is happening is that the parent isnt opening the FIFO to write into it, but why??
Thanks so much!!
Code:
/* Named pipe pipe1.c */
/* Usage: pipe1 pipename. Child reads a message from parent */
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <limits.h>
#include <errno.h>
# define BUFSIZE 256
void main(int argc, char *argv[])
{
mode_t fifo_mode = S_IRUSR | S_IWUSR;
int fd, status;
char buf[BUFSIZE];
unsigned strsize;
if (argc !=2) {
printf ("\n Usage: %s pipename\n", argv[0]);
exit(1);
}
/* generate a named pipe with r/w for user */
if ((mkfifo(argv[1],fifo_mode) == -1) && (errno != EEXIST)) {
perror ("Pipe");
exit(1);
}
switch (fork()) {
case -1:
perror ("Fork");
exit(1);
case 0:
printf ("\n Child %ld is about to open FIFO %s\n", (long)getpid(), argv[1]);
if ((fd = open(argv[1], O_RDONLY | O_NONBLOCK )) == -1)
{
perror("child cannot open FIFO");
exit(1);
}
printf ("Child is about to read\n", (long)getpid());
if (read(fd, buf, BUFSIZE) <=0)
{
perror("Child read from FIFO failed\n");
exit(1);
}
printf ("Child %ld received: %s\n", (long)getpid(), buf);
default:
/* parent does a write */
printf ("Parent %ld is about to open FIFO %s\n", (long) getpid(), argv[1]);
if ((fd = open(argv[1], O_WRONLY )) == -1)
{
perror("Parent cannot open FIFO");
exit(1);
}
sprintf (buf, "This was written by Parent %ld\n", (long)getpid());
strsize = strlen(buf) + 1;
while ((wait(&status) == -1) && (errno == EINTR));
if (write(fd, buf, strsize) != strsize)
{
printf("Parent write to FIFO failed\n");
exit(1);
}
printf ("Parent %ld is done\n", (long)getpid());
}
exit(0);
}
"Resource temporarily unavailable" is EAGAIN, aka EWOULDBLOCK... You will get it
only on file descriptors that you have explicitly set to non-blocking I/O mode... And, it
indicates that your I/O operation would normally have blocked at that point, because
it couldn't occur immediately... (Ie: for reading, there's currently no data to read; for
writing, the buffer is full and needs to be emptied first...)
Got to work, dont know what I changed but here is the updated code
I think the O_NONBLOCK was screwing things up..I still dont understand what that does...but when I took it out, it did what it was supposed to do...I took out the wait(&status) function as well...why did that fix my problem..anyone know?
Here is the final code:
Code:
nclude <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <limits.h>
#include <errno.h>
# define BUFSIZE 100
void main(int argc, char *argv[]){
mode_t fifo_mode = S_IRUSR | S_IWUSR;
int fd, status, child;
char buf[BUFSIZE];
unsigned strsize;
if (argc !=2) {
printf ("\n Usage: %s pipename\n", argv[0]);
exit(1);
}
if ((mkfifo(argv[1]), fifo_mode) == -1) && (errno != EEXIST)){
perror("Pipe");
exit(1);
}
if (( child = fork()) == -1){
perror("Fork");
exit(1);
}
else if (child == 0){
printf("\nChild %ld is about to open FIFO %s\n", (long)getpid(), argv[1]);
if ((fd = open(argv[1], O_RDONLY )) == -1){
perror("Child cannot open FIFO");
exit(1);
}
printf("Child is about to read\n", (long)getpid());
//sleep(1);
if (read(fd, buf, BUFSIZ) <= 0){
perror("Child read from FIFO failed\n");
exit(1);
}
printf("\nChild %ld received: %s\n", (long)getpid(), buf);
}
else {
printf("\nParent %ld is about to open FIFO %s\n", (long)getpid(), argv[1]);
if((fd = open(argv[1], O_WRONLY)) == -1){
perror("Parent cannot open FIFO");
exit(1);
}
/*in the parent*/
sprintf(buf, "This was written by parent %ld\n", (long)getpid());
strsize = strlen(buf) + 1;
if(write(fd, buf, strsize) != strsize)
{
printf("Parent write to FIFO failed \n");
exit(1);
}
I think the O_NONBLOCK was screwing things up...
I still dont understand what that does...but when I took it out, it did what it was supposed to do...
Because 'read' funtion is blocked until there are something ready to read. You could try out O_NONBLOCK mode as well but you have to check return value of 'read' function in child process. If it return EAGAIN, you should read fd again.
Quote:
Originally Posted by mashhype
I took out the wait(&status) function as well...why did that fix my problem..anyone know?
All of these system calls are used to wait for state changes in a child of the calling process, and obtain information about the child whose state has changed. A state change is considered to be: the child terminated; the child was stopped by a signal; or the child was resumed by a signal. In the case of a terminated child, performing a wait allows the system to release the resources associated with the child; if a wait is not performed, then terminated the child remains in a "zombie" state
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.