Re: Getting last data from child process in Leopard
Re: Getting last data from child process in Leopard
- Subject: Re: Getting last data from child process in Leopard
- From: "Jordan K. Hubbard" <email@hidden>
- Date: Tue, 25 Mar 2008 15:41:23 -0700
On Mar 24, 2008, at 12:44 PM, Ingemar Ragnemalm wrote:
I am new to the list, so I apologize if this is common knowledge. I
have searched the archives (and Google) and come up with nothing
useful.
I have an application which works nicely in Tiger, but has some
major problems in Leopard. I spawn sub-processes with forkpty, and
communicate with read and write (the standard Unix calls). I use
forkpty in order to get unbuffered data, to avoid deadlocks and to
deliver data promptly to the user.
Under Tiger, this works very well. Leopard behaves very differently.
This is because your code is very racy. Signals can interrupt system
calls, including read(2), and what's happening is that your SIGCHLD is
causing the read to be interrupted and miss data. Your signal handler
("deadbeef") also should not be attempting to read from the pty since
there are a lot of operations not considered safe from signal handlers
(your results are guaranteed to be "undefined", if not outright
incorrect). The right thing to do is check for EAGAIN in your read()
loop and go back and retry for the data in that case. Given that
you're using O_NONBLOCK, it's even more important to make sure you
handle all the async event cases.
Here is a diff to your code which will make it work less by luck, as
it did on Tiger, and more by design. I'm sure that this is also just
sample code and not something you're trying to really do in production
since looping on a non-blocking fd waiting for input is very
inefficient. That's what poll(2) is for.
- Jordan
--- forkpty.c.orig 2008-03-25 15:35:16.000000000 -0700
+++ forkpty.c 2008-03-25 15:34:22.000000000 -0700
@@ -57,6 +57,7 @@
// Wait for result
while (!done)
{
+try_again:
i = 255; // buffer size
i = read(pty, s, i);
if (i>0)
@@ -64,8 +65,11 @@
s[i] = 0;
printf("Read %d: <%s>\n", i, s);
}
- else
+ else {
printf("*");
+ if (errno == EAGAIN)
+ goto try_again;
+ }
sleep(1);
}
% uname -a
Darwin watusi9.apple.com 9.2.2 Darwin Kernel Version 9.2.2: Tue Mar 4
21:23:43 PST 2008; root:xnu-1228.4.31~1/RELEASE_PPC Power Macintosh
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden