indragie
indragie

Reputation: 18122

Using NSTask: app freezing after returning output

Hi I have the following code:

- (IBAction)runTask:(id)sender {
    NSTask *proc;
    NSPipe *output;
    NSData *data;
    NSString *buffer;

    proc = [[NSTask alloc] init];
    output = [[NSPipe alloc] init];

    [proc setLaunchPath:@"/bin/sh"];
    [proc setArguments:[NSArray arrayWithObjects: @"-c", @"/usr/bin/otool -L /Applications/TextEdit.app/Contents/MacOS/TextEdit | /usr/bin/awk 'NR>1{print $1}' | /usr/bin/sed -e '/@executable_path/d' -e 's/(.*)$//' -e  's/\\/Versions.*$//'", nil]];
    [proc launch];

    data = [[output fileHandleForReading] readDataToEndOfFile];
    buffer = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
    NSLog(@"got: %@", buffer);

     // Release
     [proc release];
     [output release];
     [buffer release];
     [data release];
}

The codes purpose is kinda complicated, it uses otool to get a list of the shared libraries used by a binary then it uses sed and awk to filter it into a machine readable format. Just to test I've used the Mac OS X TextEdit.app's binary.

The issue is that the code runs and returns an output but then freezes the app. I went through it line by line and found this line to be the problem:

data = [[output fileHandleForReading] readDataToEndOfFile];

This line itself is logging the output to the console and then freezing the app. I checked this by deleting all other lines after that line, and it still logs the output and freezes. There is nothing in debugger and any suggestions on how to solve this problem would be greatly appreciated.

Upvotes: 1

Views: 1190

Answers (4)

indragie
indragie

Reputation: 18122

The solution to this problem was simple,

Its a known bug that after NSTask is executed all logging does not work. It is returning an output, its just not logging it. The solution was to add this line:

[task setStandardInput:[NSPipe pipe]];

And everything works fine :)

Upvotes: 1

Peter N Lewis
Peter N Lewis

Reputation: 17811

output should be created with [NSPipe pipe] (unowned) and then output should be set as the standard output with [proc setStandardOutput: output]

But the reason you are crashing is because you are releasing data which you did not alloc, new or copy. See the memory management rules.

Also, see Quickies for NSTask for a nice clean implementation of this code.

Upvotes: 0

Peter Hosey
Peter Hosey

Reputation: 96333

You have an extra slash at the end of the last sed statement. Once you remove it, the script works fine.

Upvotes: 0

kubi
kubi

Reputation: 49364

It looks like you're missing a

[proc setStandardOutput:output];

Upvotes: 2

Related Questions