linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* forkpty with streams
@ 2003-07-24 23:28 Andrew Barton
  2003-07-25 13:02 ` Doug McNaught
  2003-07-25 15:27 ` Andries Brouwer
  0 siblings, 2 replies; 7+ messages in thread
From: Andrew Barton @ 2003-07-24 23:28 UTC (permalink / raw)
  To: linux-kernel

I've got the 2.4 kernel, and I'm trying to use the forkpty() system call
with the standard I/O stream functions. The calls to forkpty() and
fdopen() and fprintf() all return successfully, but the data never seems
to get to the child process. In this simplified example, I am trying to
open a shell in a pseudo terminal and then send it the string "exit\n"
and then wait for it to die. But the shell apparently never sees the
"exit\n", and the parent waits forever.

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

main()
{
	int fd;
	pid_t pid;

	pid = forkpty (&fd, 0, 0, 0);
	if (pid == 0) {
		execlp ("sh", "sh", (void *)0);
		_exit (1);
	} else if (pid == -1) {
		return 1;
	} else {
		FILE *F;

		F = fdopen (fd, "w");
		fprintf (F, "exit\n");
		fflush (F);
		wait (0);
	}
	return 0;
}



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: forkpty with streams
  2003-07-25 15:27 ` Andries Brouwer
@ 2003-07-25 10:59   ` Andrew Barton
  2003-07-25 18:46     ` Matti Aarnio
  2003-07-25 20:10     ` Andries Brouwer
  0 siblings, 2 replies; 7+ messages in thread
From: Andrew Barton @ 2003-07-25 10:59 UTC (permalink / raw)
  To: aebr; +Cc: linux-kernel

On Fri, 2003-07-25 at 15:27, Andries Brouwer wrote:
> On Thu, Jul 24, 2003 at 11:28:36PM +0000, Andrew Barton wrote:
> 
> > I've got the 2.4 kernel, and I'm trying to use the forkpty() system call
> 
> forkpty is not a system call
> 
> > with the standard I/O stream functions. The calls to forkpty() and
> > fdopen() and fprintf() all return successfully, but the data never seems
> > to get to the child process.
> 
> > 	pid = forkpty (&fd, 0, 0, 0);
> > 	if (pid == 0) {
> > 		execlp ("sh", "sh", (void *)0);
> > 	} else {
> > 		F = fdopen (fd, "w");
> > 		fprintf (F, "exit\n");
> > 		fflush (F);
> > 		wait (0);
> > 	}
> 
> Let me see. Your sh gets input from this pseudotty and sends its
> output there again. But you never read that filedescriptor.
> No doubt things will improve if you let the parent read from fd.
> 
> Andries

Before I tried using streams, I just used write() to communicate with
the ptty, but I had the same problem. I found that if I put a read()
call before and after the write(), it worked. But why? Is this some kind
of I/O voodoo? How does the reading affect the writing?

You mentioned that things would improve if I let the parent read from
fd. Will this work using streams? I have tried opening fd in "r+" mode,
but in that case I end up reading my own data. Do I need to lay an
fflush() somewhere inbetween? What is it exactly that causes the data to
be sent to the parent?

I appreciate the help.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: forkpty with streams
  2003-07-25 18:46     ` Matti Aarnio
@ 2003-07-25 12:53       ` Andrew Barton
  0 siblings, 0 replies; 7+ messages in thread
From: Andrew Barton @ 2003-07-25 12:53 UTC (permalink / raw)
  To: Matti Aarnio; +Cc: linux-kernel

On Fri, 2003-07-25 at 18:46, Matti Aarnio wrote:

> dup() helps you to have two fd:s,  fdopen() for both, one with "w",
> other "r".   Things should not need that dup() actually.
> Also fcntl() the fd's to be non-blocking.
> 
> Actually I am always nervous with stdio streams in places
> where I want to use non-blocking file handles, and carefull
> read()ing and write()ng along with select()s to handle
> non-stagnation of this type of communications.
> 

In my program, the standard input is filtered through a lex scanner
whose output file is the pty. So it does indeed need to be a stream.
Since I'm using flex, I won't have much control over the writing
process. When will it be necessary to read from the pty, to prevent a
deadlock? After each character the user types?

I might use SIGIO to read from the pty, but I have the 2.4 kernel that
doesn't support SIGIO on pipes and FIFOs. I assume ptys have the same
problem.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: forkpty with streams
  2003-07-24 23:28 forkpty with streams Andrew Barton
@ 2003-07-25 13:02 ` Doug McNaught
  2003-07-25 15:27 ` Andries Brouwer
  1 sibling, 0 replies; 7+ messages in thread
From: Doug McNaught @ 2003-07-25 13:02 UTC (permalink / raw)
  To: Andrew Barton; +Cc: linux-kernel

Andrew Barton <andrevv@users.sourceforge.net> writes:

> I've got the 2.4 kernel, and I'm trying to use the forkpty() system call
> with the standard I/O stream functions. The calls to forkpty() and
> fdopen() and fprintf() all return successfully, but the data never seems
> to get to the child process. In this simplified example, I am trying to
> open a shell in a pseudo terminal and then send it the string "exit\n"
> and then wait for it to die. But the shell apparently never sees the
> "exit\n", and the parent waits forever.

forkpty() is not a system call.  This is more likely to be a glibc
issue or a problem with your code.  You might consider running your
test under 'strace' to see what is happening under the covers.

-Doug

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: forkpty with streams
  2003-07-24 23:28 forkpty with streams Andrew Barton
  2003-07-25 13:02 ` Doug McNaught
@ 2003-07-25 15:27 ` Andries Brouwer
  2003-07-25 10:59   ` Andrew Barton
  1 sibling, 1 reply; 7+ messages in thread
From: Andries Brouwer @ 2003-07-25 15:27 UTC (permalink / raw)
  To: Andrew Barton; +Cc: linux-kernel

On Thu, Jul 24, 2003 at 11:28:36PM +0000, Andrew Barton wrote:

> I've got the 2.4 kernel, and I'm trying to use the forkpty() system call

forkpty is not a system call

> with the standard I/O stream functions. The calls to forkpty() and
> fdopen() and fprintf() all return successfully, but the data never seems
> to get to the child process.

> 	pid = forkpty (&fd, 0, 0, 0);
> 	if (pid == 0) {
> 		execlp ("sh", "sh", (void *)0);
> 	} else {
> 		F = fdopen (fd, "w");
> 		fprintf (F, "exit\n");
> 		fflush (F);
> 		wait (0);
> 	}

Let me see. Your sh gets input from this pseudotty and sends its
output there again. But you never read that filedescriptor.
No doubt things will improve if you let the parent read from fd.

Andries


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: forkpty with streams
  2003-07-25 10:59   ` Andrew Barton
@ 2003-07-25 18:46     ` Matti Aarnio
  2003-07-25 12:53       ` Andrew Barton
  2003-07-25 20:10     ` Andries Brouwer
  1 sibling, 1 reply; 7+ messages in thread
From: Matti Aarnio @ 2003-07-25 18:46 UTC (permalink / raw)
  To: Andrew Barton; +Cc: aebr, linux-kernel

On Fri, Jul 25, 2003 at 10:59:04AM +0000, Andrew Barton wrote:
...
> > > with the standard I/O stream functions. The calls to forkpty() and
> > > fdopen() and fprintf() all return successfully, but the data never seems
> > > to get to the child process.
> > 
> > > 	pid = forkpty (&fd, 0, 0, 0);
> > > 	if (pid == 0) {
> > > 		execlp ("sh", "sh", (void *)0);
> > > 	} else {
> > > 		F = fdopen (fd, "w");
> > > 		fprintf (F, "exit\n");
> > > 		fflush (F);
> > > 		wait (0);
> > > 	}
...
> Before I tried using streams, I just used write() to communicate with
> the ptty, but I had the same problem. I found that if I put a read()
> call before and after the write(), it worked. But why? Is this some kind
> of I/O voodoo? How does the reading affect the writing?

PTY file-handle is full-duplex bi-directional thing, and sometimes
it may need reading, or you get unwanted deadlocks.

> You mentioned that things would improve if I let the parent read from
> fd. Will this work using streams? I have tried opening fd in "r+" mode,
> but in that case I end up reading my own data. Do I need to lay an
> fflush() somewhere inbetween? What is it exactly that causes the data to
> be sent to the parent?

dup() helps you to have two fd:s,  fdopen() for both, one with "w",
other "r".   Things should not need that dup() actually.
Also fcntl() the fd's to be non-blocking.

Actually I am always nervous with stdio streams in places
where I want to use non-blocking file handles, and carefull
read()ing and write()ng along with select()s to handle
non-stagnation of this type of communications.

> I appreciate the help.

/Matti Aarnio

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: forkpty with streams
  2003-07-25 10:59   ` Andrew Barton
  2003-07-25 18:46     ` Matti Aarnio
@ 2003-07-25 20:10     ` Andries Brouwer
  1 sibling, 0 replies; 7+ messages in thread
From: Andries Brouwer @ 2003-07-25 20:10 UTC (permalink / raw)
  To: Andrew Barton; +Cc: linux-kernel

On Fri, Jul 25, 2003 at 10:59:04AM +0000, Andrew Barton wrote:
> On Fri, 2003-07-25 at 15:27, Andries Brouwer wrote:
> > On Thu, Jul 24, 2003 at 11:28:36PM +0000, Andrew Barton wrote:

> > > the data never seems to get to the child process.
> > 
> > > 	pid = forkpty (&fd, 0, 0, 0);
> > > 	if (pid == 0) {
> > > 		execlp ("sh", "sh", (void *)0);
> > > 	} else {
> > > 		F = fdopen (fd, "w");
> > > 		fprintf (F, "exit\n");
> > > 		fflush (F);
> > > 		wait (0);
> > > 	}
> > 
> > Let me see. Your sh gets input from this pseudotty and sends its
> > output there again. But you never read that filedescriptor.
> > No doubt things will improve if you let the parent read from fd.
> > 
> > Andries
> 
> Before I tried using streams, I just used write() to communicate with
> the ptty, but I had the same problem. I found that if I put a read()
> call before and after the write(), it worked. But why? Is this some kind
> of I/O voodoo? How does the reading affect the writing?

You test with bash, which is a complicated program with many
subtleties related to job control and terminal control. Things will be
easier with ash instead of sh.

But to answer your concrete question: bash does
	ioctl(0, TCSETSW, foo);
which is the same as POSIX
	tcsetattr(0, TCSADRAIN, foo);
which does some setting, but first waits for the output buffer to drain.
It will never drain, unless the other side of the pty does some reading.

Andries


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2003-07-25 19:54 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-07-24 23:28 forkpty with streams Andrew Barton
2003-07-25 13:02 ` Doug McNaught
2003-07-25 15:27 ` Andries Brouwer
2003-07-25 10:59   ` Andrew Barton
2003-07-25 18:46     ` Matti Aarnio
2003-07-25 12:53       ` Andrew Barton
2003-07-25 20:10     ` Andries Brouwer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).