Hey all. I don't want to be one of those that sounds like HW but they didn't say it was so I'll be honest, this is HW but I feel like I've done enough that it's reasonable to ask for a little help here. This is a snippet from a bigger assignment where we're writing a suite that communicates using a bunch of IPC methods and I've finished most of them. The code below is what I've written for the sockets section:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>

#define BUFFER_SIZE 25
#define READ_END	0
#define WRITE_END	1

int main(void)
{
	char write_msg[BUFFER_SIZE] = "Greetings";
	char read_msg[BUFFER_SIZE];
	pid_t pid;
	int fd[2];

	/** create the pipe */
	if (pipe(fd) == -1) {
		fprintf(stderr,"Pipe failed");
		return 1;
	}
//printf("fd[0]=%d fd[1]=%d\n", fd[0], fd[1]);

	/** now fork a child process */
	pid = fork();

	if (pid < 0) {
		fprintf(stderr, "Fork failed");
		return 1;
	}

	if (pid > 0) {  /* parent process */
		/* close the unused end of the pipe */
		close(fd[READ_END]);

		/* write to the pipe */
		write(fd[WRITE_END], write_msg, strlen(write_msg)+1);

		/* close the write end of the pipe */
		close(fd[WRITE_END]);
	}
	else { /* child process */
		/* close the unused end of the pipe */
		close(fd[WRITE_END]);

		/* read from the pipe */
		read(fd[READ_END], read_msg, BUFFER_SIZE);
		printf("child read from parent:  [%s]\n",read_msg);

		/* close the write end of the pipe */
		close(fd[READ_END]);
	}

	return 0;
}

The current code compiles and runs fine but all I've been able to get it to do is get the child to read from the parent. What I'd like to have it do is fork the child and then simply have the child read from parent(which i've done) and have the child reply to the parent if it gets the message it is expecting.

So, how do I make this child check the incoming message(the part I'm having the most trouble with) against a phrase and then reply to the parent with its own phrase?

I hope I've done enough work on the program that no one minds me asking for some hw help but if it's not cool just let me know and I'll drop the thread.

Namaste,
-Ray-

Recommended Answers

All 5 Replies

Try something like below..I would go over the code because I wrote this quickly

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>

#define BUFFER_SIZE 25
#define READ_END	0
#define WRITE_END	1

int main(void)
{
	char write_msg[BUFFER_SIZE] = "Greetings";
	char read_msg[BUFFER_SIZE];
	pid_t pid;
	int fd[2];

	if (pipe(fd) == -1) 
	{
		fprintf(stderr,"Pipe failed");
		return 1;
	}

	pid = fork();

	if (pid < 0) 
	{
		fprintf(stderr, "Fork failed");
		return 1;
	}

	if (pid > 0) 
	{ 
		char ch;
		write(fd[WRITE_END], write_msg, strlen(write_msg) + 1);
		
		while (read(fd[READ_END], (char*)&ch, sizeof(char)), ch != '\n')
		{
			fputc(ch, stdout);
		}
		fputc('\n', stdout);

		close(fd[READ_END]);		
		close(fd[WRITE_END]);
	}
	else 
	{

		char the_return_message[] = "this is the return message!\n";

		read(fd[READ_END], read_msg, BUFFER_SIZE);
		printf("child read from parent:  [%s]\n",read_msg);
		write(fd[WRITE_END], the_return_message, strlen(the_return_message));

		close(fd[WRITE_END]);
		close(fd[READ_END]);
	}

	return 0;
}

Thank you for your speedy reply! I added in the condition where the child is going to check for the expected message from the parent and return its response but it's not working correctly. The code never enters the if statement it just skips past and says wrong message received. This is pretty simple I'm sure but I'm not making headway debugging it.

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>

#define BUFFER_SIZE 25
#define READ_END	0
#define WRITE_END	1

int main(void)
{
	char write_msg[BUFFER_SIZE] = "How are you my child?";
	char read_msg[BUFFER_SIZE];
	pid_t pid;
	int fd[2];

	if (pipe(fd) == -1)
	{
		fprintf(stderr,"Pipe failed");
		return 1;
	}

	pid = fork();

	if (pid < 0)
	{
		fprintf(stderr, "Fork failed");
		return 1;
	}

	if (pid > 0)
	{
		char ch;
		write(fd[WRITE_END], write_msg, strlen(write_msg) + 1);

		while (read(fd[READ_END], (char*)&ch, sizeof(char)), ch != '\n')
		{
			fputc(ch, stdout);
		}
		fputc('\n', stdout);

		close(fd[READ_END]);
		close(fd[WRITE_END]);
	}
	else
	{

		char the_return_message[] = "I am fine thank you!\n";

        if(write_msg == "How are you my child?")
            {
            read(fd[READ_END], read_msg, BUFFER_SIZE);
            printf("child read from parent:  [%s]\n",read_msg);
            write(fd[WRITE_END], the_return_message, strlen(the_return_message));

            close(fd[WRITE_END]);
            close(fd[READ_END]);
            }
                else
                {
                printf("Did not recieve the correct message\n");
                }
	}

	return 0;
}

Line 50

write_msg == "How are you my child?"

This compares pointer values. If you want to test the c-strings for equality then use strcmp() or use a C++ string object.

The code you suggested leads to the race with a high chance of a deadlock:

write(fd[WRITE_END], write_msg, strlen(write_msg) + 1);		
		while (read(fd[READ_END], (char*)&ch, sizeof(char)), ch != '\n')
		{
			...
		}

Here the parent would immediately read back whatever it just wrote, eventually leaving both processes hung at the read().

The only way to establish two way communication is to set up two pipes.

Like nezachem explained, you need a second pipe for the return message, you can't use the same one.

Imagine having the parent process spawn 5 child processes. You would need 6 pipes, 5 for parent -> child communication, and the 6th pipe for the return communication child-> parent.

Hope this helps.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.