Re: trying to control the output of a subprocess.
Re: trying to control the output of a subprocess.
- Subject: Re: trying to control the output of a subprocess.
- From: Nicholaz Beresford <email@hidden>
- Date: Thu, 04 Sep 2008 11:45:55 +0200
Just guessing but if you can get a posix stream (FILE *)
you can try to use setbuf(stream, NULL); Under posix
functions I'd do that after the fork() before exec()
but I have no idea how this works in Cocoa.
Nick
Paul Archibald wrote:
Hey folks,
MyApp is a GUI to a command line program (CLP) to which I do not have
the source code. MyApp asks the user to select a directory, makes a list
of the files in that directory, and calls the CLP for each file. The CLP
processes the file(s), reporting its progress to the console with a
message like "filename : block 2 finished" until it is finished
"filename : finished." I use that output to inform the progressbars and
other elements of my GUI.
Well, it worked fine up until now, when I am doing some testing and am
launching MyApp from the Finder instead of from Xcode. Now, the progress
output is being buffered until the CPL is finished with the file, and
then spewing out the entire buffer (which MyApp has been intercepting).
This is abd for me since I need that line by line output.
I have seen some posts on the Cocoa and Xcode lists that mention similar
problems, but I can't find one that explains how to fix it. I am using
the TaskWrapper class from the Moriarity sample to execute my tasks.
Here is how TaksWrapper sets up the NSTask that it uses:
////////
- (void) startProcess {
// We first let the controller know that we are starting
[controller processStarted:self];
task = [[NSTask alloc] init];
// The output of stdout and stderr is sent to a pipe so that we can
catch it later
// and send it along to the controller; notice that we don't bother
to do anything with stdin,
// so this class isn't as useful for a task that you need to send
info to, not just receive.
[task setStandardOutput: [NSPipe pipe]];
[task setStandardError: [task standardOutput]];
// The path to the binary is the first argument that was passed in
[task setLaunchPath: [arguments objectAtIndex:0]];
// The rest of the task arguments are just grabbed from the array
[task setArguments: [arguments subarrayWithRange: NSMakeRange (1,
([arguments count] - 1))]];
// Here we register as an observer of the
NSFileHandleReadCompletionNotification, which lets
// us know when there is data waiting for us to grab it in the
task's file handle (the pipe
// to which we connected stdout and stderr above). -getData: will
be called when there
// is data waiting. The reason we need to do this is because if the
file handle gets
// filled up, the task will block waiting to send data and we'll
never get anywhere.
// So we have to keep reading data from the file handle as we go.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(getData:)
name: NSFileHandleReadCompletionNotification
object: [[task standardOutput] fileHandleForReading]];
// We tell the file handle to go ahead and read in the background
asynchronously, and notify
// us via the callback registered above when we signed up as an
observer. The file handle will
// send a NSFileHandleReadCompletionNotification when it has data
that is available.
[[[task standardOutput] fileHandleForReading]
readInBackgroundAndNotify];
// launch the task asynchronously
[task launch];
// some stuff I added just to see what is going on
int pid = [task processIdentifier];
NSLog(@"pid == %d", pid); // this worked
NSLog(@"tty == %s", ttyname(pid)); // result is (null)
}
/////////
So, does anyone know what to do to fix this? Is it the way the notifier
is getting set up? Something about the file handles or the pipe that
could be set up differently? It seems as though what I want is control
the buffering of the standard output, but I don't know how.
Any ideas?
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden