Getting last data from child process in Leopard
site_archiver@lists.apple.com Delivered-To: darwin-dev@lists.apple.com User-agent: Thunderbird 2.0.0.12 (Macintosh/20080213) Dear list, Under Tiger, this works very well. Leopard behaves very differently. Here is an example program: ------------- #include <stdio.h> #include <stdlib.h> #include <util.h> #include <stdint.h> #include <fcntl.h> #include <sys/filio.h> #include <sys/errno.h> void hello() { printf("hello!\n"); sleep(2); printf("there!\n"); sleep(2); printf("BYE!\n"); } int pty; int done = 0; printf("aaarrrggh!\n"); done = 1; } /Ingemar _______________________________________________ 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. Tiger is actually very friendly; when the sub-process terminates, it seems to keep it open until I have read all data from it, and only when fully drained it really terminates. Under Leopard, it dies if I call waitpid(), which is legal. No problem, I keep reading until I get nothing, and then I check with waitpid(). This seems to work if I have a tight loop polling the fd, but if I don't poll all the time, any data sent close to termination is lost. OK, I thought, so I catch the SIGCHLD signal to know when it terminates? No go, when I get the signal, the data is already trashed, that is, I get nothing from read. void deadbeef(int a) { int i; char name[255]; i = 100; i = read(pty, name, i); if (i > 0) printf("Signal handler read %d %s\n", i, name); else printf("Signal handler read nothing\n"); main() { int pid, i, err; int mypid, ohyes; char s[255]; if (( pid = forkpty( &(pty), NULL, NULL, NULL) ) < 0) { // Failure printf( "Forking error\n"); exit(-1); } if (0 == pid) { // Slave - child process hello(); exit( 0); } // Otherwise parent process int flags; // set file to non-blocking */ flags = fcntl(pty, F_GETFL, 0); if (0 != fcntl(pty, F_SETFL, flags | O_NONBLOCK)) printf( "fcntl error"); if( SIG_ERR == signal( SIGCHLD, deadbeef)) printf( "SIGCHLD error"); // Wait for result while (!done) { i = 255; // buffer size i = read(pty, s, i); if (i>0) { s[i] = 0; printf("Read %d: <%s>\n", i, s); } else printf("*"); sleep(1); } exit(0); } ------------ Under Tiger, it seems to work pretty well. Under Leopard, the "bye" line is always lost! Something significant has changed in Leopard! How do I get the last data from the child process when it terminates? This email sent to site_archiver@lists.apple.com
participants (1)
-
Ingemar Ragnemalm