InterProcess Communication on MacOSX Lion
Asked Answered
T

1

1

I'm trying to figure out how to set up IPC between my custom app and a pre-made program.
I'm using MacOSX Lion 10.7.2 and Xcode 4.2.1.

It doesn't matter actually what program exactly, since I believe that a similar reasoning may be applied to any kind of external process.
For testing purposes I'm using a simple bash script:

#test.sh
echo "Starting"
while read out 
do 
    echo $out
done

What I would like to achieve is to redirect input and output of this script, using my app to send inputs to it and read its outputs.

I tried to use NSTask,NSPipe and NSFileHandle as follows:

-(void)awakeFromNib {

    task = [[NSTask alloc] init];

    readPipe = [NSPipe pipe];
    writePipe = [NSPipe pipe];

    [task setStandardOutput:readPipe];
    [task setStandardInput:writePipe];    

    [task setLaunchPath:@"/path/test.sh"];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(read:)
                                                 name:NSFileHandleReadCompletionNotification
                                               object:nil];

    [[readPipe fileHandleForReading] readInBackgroundAndNotify];

    [task launch];

}

-(IBAction)write:(id)sender {

    NSLog(@"Write called: %d %@\n",[task isRunning],writePipe);

    NSFileHandle *writeHandle = [writePipe fileHandleForWriting];

    NSString *message = @"someString";

    [writeHandle writeData:[message dataUsingEncoding:NSUTF8StringEncoding] ];

}

-(void)read:(NSNotification*)notification {

    NSString *output = [[NSString alloc] initWithData:[[notification userInfo] valueForKey: NSFileHandleNotificationDataItem]
                                             encoding:NSUTF8StringEncoding];

    NSLog(@"%@",output);

    [output release];

    [[notification object] readInBackgroundAndNotify]; 

}

but I'm able only to read the output of test.sh, not to send it any input.

Actually any other example I saw on the web is pretty similar to my code, so I'm not sure if this issue is due to some mistake(s) of mine or to other issues (like app's sandboxing of MacOS Lion).

I've checked XPC documentation, but, according to my researches, in order to use XPC API to IPC, both sides should connect to the same service.
That's not what I'm looking for since I don't want to alter the script in any way, I just want redirect its input and output.

Is my issue due to the lack of XPC and/or to app's sandboxing?

If yes, is there a way to use XPC without modifying the script?
If no, then may somebody explain me what I'm doing wrong?

Teirtza answered 16/3, 2012 at 18:53 Comment(0)
R
1

You don't need XPC for this. Won't make any difference.

Is your script / external process able to read input when you pipe something to it on the command line

% echo "foobar" | /path/test.sh

?

How much data are you sending to it. Writing will be buffered. IIRC -synchronizeFile will flush buffers -- same as fsync(2).

Reeder answered 27/3, 2012 at 12:50 Comment(1)
Thank you for your answer. Yes, from command line the script works fine. From my program I'm sending just "someString", as you can see from the code. Using [writeHandle synchronizeFile]; has resulted in [NSConcreteFileHandle synchronizeFile]: Operation not supportedTeirtza

© 2022 - 2024 — McMap. All rights reserved.