Re: Problem with redirecting stdout
Re: Problem with redirecting stdout
- Subject: Re: Problem with redirecting stdout
- From: Dave Keck <email@hidden>
- Date: Wed, 10 Nov 2010 00:08:09 -0500
> I think the problem is that the pipe buffer is not being flushed/read when
> it's full; when the pipe is full, the script interpreter then is blocked
> because it's waiting for the pipe to empty so that it can write.
I don't fully understand the structure of your program, but indeed it
sounds like the classic filled-buffer hang.
I would solve your problem by using GCD and avoiding
NSPipe/NSFileHandle altogether. To prevent the child from hanging when
it attempts to write() to its stdout, you need to make sure the parent
is always going to read the available data in the buffer as soon as
it's available. You can accomplish this without too much trouble:
==========
#define BUFFER_SIZE 0x1000
dispatch_source_t source =
dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, readFD, 0,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
dispatch_source_set_event_handler(source,
^{
void *dataBuffer = malloc(BUFFER_SIZE);
assert(dataBuffer);
ssize_t readResult = 0;
do
{
errno = 0;
readResult = read(readFD, dataBuffer, BUFFER_SIZE);
} while (readResult == -1 && errno == EINTR);
assert(readResult >= 0);
if (readResult > 0)
{
dispatch_async(dispatch_get_main_queue(),
^{
NSString *newDataString = [[[NSString alloc]
initWithBytesNoCopy: dataBuffer
length: readResult encoding: NSUTF8StringEncoding
freeWhenDone: YES] autorelease];
// append newDataString to the NSTextView...
});
}
else
free(dataBuffer);
});
==========
Hopefully that gets the idea across – of course it needs more robust
error-checking and such.
> I've also tried using an pseudo-tty via openpty() instead of an NSPipe, but
> I get the same problem: The app hangs when too much output is sent to stdout
> by an executing script.
Using a PTY instead of an unnamed pipe wouldn't fix the problem. All
using a PTY would do is cause the child's Libc buffer to be flushed
after each newline rather than when the Libc buffer is filled. That
behavior might be useful, though, if it's preferable that your parent
reads the child's output by line rather than by some constant-sized
number of bytes.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden