bugfixr
bugfixr

Reputation: 8077

bundlePath returns empty when running as a Launch Deamon on MacOSX 10.5

I've got a Cocoa command-line app which is built to target 10.5 SDK. In the app, I have

NSString *appPath = [[NSBundle mainBundle] bundlePath];
NSLog(@"%@", appPath);

On Mac OSX 10.5, when I run the app from the command line, I get the expected output of the path. However, if I set the app up to run as a LaunchDeamon, it only outputs a '/'

It works as expected on 10.6 and on 10.7 both as a Deamon and as an app. Anyone know why the difference would be? Is there a better way to get the application path that would work on 10.5+?

UPDATE

For me, the solution in the accepted answer did not work. However, the comment about adding the "WorkingDirectory" key to the LaunchDeamon's plist file worked out. Apparently this is needed for Mac OS X 10.5, but not 10.6+.

Upvotes: 0

Views: 192

Answers (1)

Michael Dautermann
Michael Dautermann

Reputation: 89509

Thanks for answering my clarifying question.

NSBundle depends on a existing bundle, with it's associated Info.plists and bundle ID's (e.g. com.apple.textedit.app), etc.

While a single binary is not a bundle, I'm guessing that Apple engineering fixed up [[NSBundle mainBundle] bundlePath] to do "the right thing" in 10.6 & 10.7. But you still need a solution for 10.5.

Maybe the UNIX library function char * getcwd(char *buf, size_t size) would get you to where you need to be.

For a proper solution, I'd recommend doing a run-time conditional check with code that looks something like this:

+ (NSString *) getAppPath
{
    NSString * appPath = NULL;
    SInt32  minorVersionNum;
    OSErr   err;

    err = Gestalt(gestaltSystemVersionMinor,&minorVersionNum);

    // do this only if we're running on anything *older* than 10.6
    if((noErr == err) && (minorVersionNumber < 6)) 
    {
        // hopefully the below define is enough space for any returned path
        #define kMaxPathLength 512 

        size_t bufferLength = kMaxPathLength;
        char bufferToHoldPath[kMaxPathLength]; 

        // initialize the buffer & guarantee null-terminated strings
        bzero(&bufferToHoldPath,bufferLength);
        if( getcwd(&bufferToHoldPath, bufferLength) != NULL)
        {
            appPath = [NSString stringWithUTF8String: bufferToHoldPath];
        }
    } 

    // this code runs for 10.6 and *newer*, and attempts it on
    // 10.5 only if the above getcwd call failed
    if(NULL == appPath)
    {
        appPath = [[NSBundle mainBundle] bundlePath];
    }

    return(appPath);
}

I did not test this code out so YMMV.

Upvotes: 1

Related Questions