• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: trying to control the output of a subprocess.
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


References: 
 >trying to control the output of a subprocess. (From: Paul Archibald <email@hidden>)

  • Prev by Date: Re: Xcode + gdb problems with exec
  • Next by Date: [Xcode 3.1] Open with Finder does not work as expected
  • Previous by thread: trying to control the output of a subprocess.
  • Next by thread: Re: trying to control the output of a subprocess.
  • Index(es):
    • Date
    • Thread