UNIX Socket FAQ

A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

#1 2008-07-26 12:09 AM

fbonales
Guest

Re: Using /dev/ptmx

Hi all,

Man page for ptmx/pts says:

Data written to the slave is presented  on  the  master  descriptor  as
input.   Data written to the master is presented to the slave as input.

I wrote the following piece of code:

#include <allheaders.h>

extern int errno;

void fatalErrrExit(int error, char *message)
{
	perror(message);
	perror(strerror(error));
	exit(1);
}

void fatalExit(char *message)
{
	perror(message);
	exit(1);
}

int main(int argc, char *argv[])
{
	char buffer[1024];
	int bufSize = 1024;
	int mfd = -1, sfd = -1;
	int red, wrote;
	pid_t pid;

	if(argc < 2)
		fatalExit("Invalid command line");
	
	if(strcmp(argv[1], "child") == 0)
	{
		if(argc != 3)
			fatalExit("Invalid command line");
				
		printf("Child role: openning parent endpoint at %s\n", argv[2]);

		if((sfd = open(argv[2], O_RDWR)) == -1)
			fatalErrorExit(errno, "Cannot open slave stream");
				
		pid = 0;
	}
		
	else if(strcmp(argv[1], "parent") == 0)
	{
		if((mfd = getpt()) == -1)
			fatalErrorExit(errno, "Cannot open stream");
				
		if(grantpt(mfd) == -1)
			fatalErrorExit(errno, "Cannot grant stream");
				
		if(unlockpt(mfd) == -1)
			fatalErrorExit(errno, "Cannot unlock stream");

		printf("Parent role: child endpoint at %s\n", ptsname(mfd));
		pid = 1;
	}
		
	else if(strcmp(argv[1], "both") == 0)
	{
		if((mfd = getpt()) == -1)
			fatalErrorExit(errno, "Cannot open stream");
				
		if(grantpt(mfd) == -1)
			fatalErrorExit(errno, "Cannot grant stream");
				
		if(unlockpt(mfd) == -1)
			fatalErrorExit(errno, "Cannot unlock stream");
		
		if((sfd = open(ptsname(mfd), O_RDWR)) == -1)
			fatalErrorExit(errno, "Cannot open slave stream");
	
		pid = fork();
	}
	
	else fatalExit("Unknown mode of operation");


	switch(pid)
	{
		case -1:
			fatalErrorExit(errno, "Cannot fork");
			break;
			
		case 0: // Child
			close(mfd);
			
			while(true)
			{
				if((wrote = write(sfd, "Hello Dad!\n", 11)) < 0)
					fatalErrorExit(errno, "Cannot write to parent");

				if((red = read(sfd, buffer, bufSize)) < 0)
					fatalErrorExit(errno, "Cannot receive from parent");
				
				else if(red == 0)
					fatalErrorExit(errno, "Parent terminated");
				
				buffer[red] = '\0';
				printf("P -> C: %s", buffer);

				sleep(random() % 10);
			}
			
			break;
			
	default: // Parent
		close(sfd);
		
		while(true)
		{
			if((wrote = write(mfd, "Hello Child!\n", 13)) < 0)
				fatalErrorExit(errno, "Cannot write to child");

			if((red = read(mfd, buffer, bufSize)) < 0)
				fatalErrorExit(errno, "Cannot receive from child");
				
			else if(red == 0)
				fatalErrorExit(errno, "Child terminated");
				
			buffer[red] = '\0';
			printf("P <- C: %s", buffer);
			
			sleep(random() % 10);
		}
		
		break;
	}
	
	return 0;
}

Everything works as I would expect, except for the following, when the parent writes its string, the child reads that string, but also the parent read the same string it wrote.

In the opposite way, doesn't work like that. When the child writes its string, only the parent reads it.

Is this the way it should work?, why?

Thanks in advance.

#2 2008-07-26 06:15 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,833
Website

Re: Using /dev/ptmx

Note: please surround large blocks of code like that with the code tags...

I'm guessing that it's probably related to the terminal settings; namely, probably the
echo setting...  Look into tcsetattr() and related termios functions...

Also, you might want to look into openpty() and/or forkpty(), which handle a lot of
the work for you...

Offline

#3 2009-05-26 12:12 AM

nishantkumar05
Guest

Re: Using /dev/ptmx

fbonales;24887 wrote:

Hi all,

Man page for ptmx/pts says:

Data written to the slave is presented  on  the  master  descriptor  as
input.   Data written to the master is presented to the slave as input.

I wrote the following piece of code:

#include <allheaders.h>

extern int errno;

void fatalErrrExit(int error, char *message)
{
	perror(message);
	perror(strerror(error));
	exit(1);
}

void fatalExit(char *message)
{
	perror(message);
	exit(1);
}

int main(int argc, char *argv[])
{
	char buffer[1024];
	int bufSize = 1024;
	int mfd = -1, sfd = -1;
	int red, wrote;
	pid_t pid;

	if(argc < 2)
		fatalExit("Invalid command line");
	
	if(strcmp(argv[1], "child") == 0)
	{
		if(argc != 3)
			fatalExit("Invalid command line");
				
		printf("Child role: openning parent endpoint at %s\n", argv[2]);

		if((sfd = open(argv[2], O_RDWR)) == -1)
			fatalErrorExit(errno, "Cannot open slave stream");
				
		pid = 0;
	}
		
	else if(strcmp(argv[1], "parent") == 0)
	{
		if((mfd = getpt()) == -1)
			fatalErrorExit(errno, "Cannot open stream");
				
		if(grantpt(mfd) == -1)
			fatalErrorExit(errno, "Cannot grant stream");
				
		if(unlockpt(mfd) == -1)
			fatalErrorExit(errno, "Cannot unlock stream");

		printf("Parent role: child endpoint at %s\n", ptsname(mfd));
		pid = 1;
	}
		
	else if(strcmp(argv[1], "both") == 0)
	{
		if((mfd = getpt()) == -1)
			fatalErrorExit(errno, "Cannot open stream");
				
		if(grantpt(mfd) == -1)
			fatalErrorExit(errno, "Cannot grant stream");
				
		if(unlockpt(mfd) == -1)
			fatalErrorExit(errno, "Cannot unlock stream");
		
		if((sfd = open(ptsname(mfd), O_RDWR)) == -1)
			fatalErrorExit(errno, "Cannot open slave stream");
	
		pid = fork();
	}
	
	else fatalExit("Unknown mode of operation");


	switch(pid)
	{
		case -1:
			fatalErrorExit(errno, "Cannot fork");
			break;
			
		case 0: // Child
			close(mfd);
			
			while(true)
			{
				if((wrote = write(sfd, "Hello Dad!\n", 11)) < 0)
					fatalErrorExit(errno, "Cannot write to parent");

				if((red = read(sfd, buffer, bufSize)) < 0)
					fatalErrorExit(errno, "Cannot receive from parent");
				
				else if(red == 0)
					fatalErrorExit(errno, "Parent terminated");
				
				buffer[red] = '\0';
				printf("P -> C: %s", buffer);

				sleep(random() % 10);
			}
			
			break;
			
	default: // Parent
		close(sfd);
		
		while(true)
		{
			if((wrote = write(mfd, "Hello Child!\n", 13)) < 0)
				fatalErrorExit(errno, "Cannot write to child");

			if((red = read(mfd, buffer, bufSize)) < 0)
				fatalErrorExit(errno, "Cannot receive from child");
				
			else if(red == 0)
				fatalErrorExit(errno, "Child terminated");
				
			buffer[red] = '\0';
			printf("P <- C: %s", buffer);
			
			sleep(random() % 10);
		}
		
		break;
	}
	
	return 0;
}


Everything works as I would expect, except for the following, when the parent writes its string, the child reads that string, but also the parent read the same string it wrote.

In the opposite way, doesn't work like that. When the child writes its string, only the parent reads it.

Is this the way it should work?, why?

Thanks in advance.

Did you by any chance happen to find out the cause ? im having same problem.
i did set -echo parameter , but it doesnt change anything.
any pointers will be highly appriciated.
thanks in advance

#4 2014-04-02 08:55 AM

/dev/null
Guest

Re: Using /dev/ptmx

Try removing echo flag by

#include<termios.h>

...

struct termios t;
tcgetattr(mfd, &t);
t.c_lflag |= ~ECHO;
tcsetattr(mfd, TCSANOW, &t);

That should remove echo when writing to master device.

Board footer

Powered by FluxBB