Re: Getting last data from child process in Leopard
site_archiver@lists.apple.com Delivered-To: darwin-dev@lists.apple.com On Mar 24, 2008, at 12:44 PM, Ingemar Ragnemalm wrote: - 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); } _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-dev mailing list (Darwin-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-dev/site_archiver%40lists.appl... 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. % 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 This email sent to site_archiver@lists.apple.com
participants (1)
-
Jordan K. Hubbard