LinuxQuestions.org
Visit the LQ Articles and Editorials section
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 11-20-2010, 08:40 PM   #1
mashhype
LQ Newbie
 
Registered: Sep 2010
Distribution: Ubuntu Linux 10.04 Lucid Lynx
Posts: 11

Rep: Reputation: 0
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);
}
 
Old 11-21-2010, 01:52 AM   #2
paulsm4
Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Off the top of my head ... don't you WANT the child to block until there's something to read?
 
Old 11-21-2010, 07:11 PM   #3
mac.tieu
Member
 
Registered: Jan 2010
Location: Vietnam
Distribution: Arch
Posts: 65

Rep: Reputation: 22
You should write to pipe before waiting for client exit. Like this:
Code:
if (write(fd, buf, strsize) != strsize) 
{ 
  printf("Parent write to FIFO failed\n"); 
  exit(1); 
}
while ((wait(&status) == -1) && (errno == EINTR));
Regards,
MT.
 
Old 11-22-2010, 01:00 AM   #4
paulsm4
Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Nonsense. You don't need a "wait()", nor do you need a busy loop if you've forked() the child and you're using a "mkfifo()" queue.

You SHOULD eliminate the "O_NONBLOCK" in your child:
Code:
  if ((fd = open(argv[1], O_RDONLY)) == -1)
    ... error handing ...
  if (read(fd, buf, BUFSIZE) <=0) 
    ... error handling ...
Specifically:
Quote:
http://developerweb.net/viewtopic.php?id=5792

"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...)

Last edited by paulsm4; 11-22-2010 at 01:04 AM.
 
1 members found this post helpful.
Old 11-22-2010, 01:48 AM   #5
mashhype
LQ Newbie
 
Registered: Sep 2010
Distribution: Ubuntu Linux 10.04 Lucid Lynx
Posts: 11

Original Poster
Rep: Reputation: 0
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);
	}
 
Old 11-22-2010, 02:43 AM   #6
mac.tieu
Member
 
Registered: Jan 2010
Location: Vietnam
Distribution: Arch
Posts: 65

Rep: Reputation: 22
Quote:
Originally Posted by mashhype View Post
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 View Post
I took out the wait(&status) function as well...why did that fix my problem..anyone know?
wait(2) - Linux man page
Quote:
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
 
1 members found this post helpful.
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Sending Signal from Child Process to Parent Process : Not getting desired output thelink123 Linux - General 4 10-26-2012 09:05 PM
ipc between parent and child processes using pipe rainman1985_2010 Programming 3 10-15-2010 03:30 AM
select() call does not detect data in pipe between parent and child program rasbambober Programming 5 09-24-2009 11:32 PM
child process usses same amount of ram as parent process socialjazz Programming 7 10-19-2006 05:48 PM
Bash Scripting - child process affecting parent process mthaddon Linux - General 1 05-02-2004 01:19 PM


All times are GMT -5. The time now is 01:17 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration