NSTask: auxiliary executable does not see its data file

  • [I posted this at discussions.apple.com, but realise that this is
    probably a more appropriate venue for a technical question]

    I am writing a simple Cocoa-ObjectiveC wrapper around a command-line
    tool written in C, and understand the basics of using NSTask, NSPipe,
    NSFileHandle and multiple executable targets. My development platform
    is Xcode 3 / Leopard.

    The Cocoa interface uses an NSTextView to display the stdout (and
    stderr, if necessary) of the CL tool, and to accept text directed to
    the tool's stdin. The message appearing in the text view on launching
    the app is that the data file is not found.

    I use a Copy Files build phase in the Xcode project to put the
    auxiliary executable in the MacOS folder of the app bundle where the
    app's executable is. The data file is there, but the tool executable
    is not seeing it when it is being run by NSTask. The tool target has
    to load a read-only data file on launch or it fails. The tool target
    builds and executes OK in the Xcode console because it has its own
    Copy Files build phase to get a copy of the data file.

    The tool tries to open the file with an ordinary call to fopen():

    f = fopen("my.data",READ_MODE);

    In windowDidLoad I've set the path for the auxiliary executable like
    this:

    path = [[ NSBundle mainBundle ] pathForAuxiliaryExecutable:
    @"BackEnd" ];

    backEnd = [[ NSTask alloc ] init ];

    //[ backEnd setCurrentDirectoryPath: [ path
    stringByDeletingLastPathComponent ] ];

    [ backEnd setLaunchPath: path ];

    Of course, I'm concerned about having had to comment out the
    setCurrentDirectoryPath operation, which I inserted on the following
    advice:

    http://cocoadev.com/wiki/UsingAuxiliaryExecutableInBundle

    There is probably something somewhere in my auxiliary executable code
    that is not working with the environment it gets as an NSTask. I am
    puzzled that the standalone tool executable has no trouble the data
    file located in the same directory from which it launches, and runs
    fine in the Xcode console. In fact, when I drill into the app bundle
    and run the tool executable down there, it is fine, of course.

    I probably have not sufficiently studied the source code for the
    auxiliary executable and the mechanics of how NSTask sets up the
    launch environment for the auxiliary. I was doing a lot of Cocoa
    programming a few years ago, when the OS was still 10.4, and I am
    trying to spin up to using 10.5 and 10.6 now, and a lot of things feel
    different. Any gentle advice will be greatly appreciated.
  • On Jul 30, 2012, at 8:08 AM, Daniel Stein <dyne2meter...> wrote:

    > The tool tries to open the file with an ordinary call to fopen():
    > f = fopen("my.data",READ_MODE);

    Of course this assumes the current directory is the one containing the my.data file. By default it won't be, because the tool inherits the current directory from the app, and IIRC when an app is launched the CWD is set to the root directory of its bundle.

    In general it's not a good idea to depend on the CWD in an app anyway. Why not pass the absolute path of the data file as a command-line argument to the tool from NSTask?

    > //[ backEnd setCurrentDirectoryPath: [ path stringByDeletingLastPathComponent ] ];
    >
    > Of course, I'm concerned about having had to comment out the setCurrentDirectoryPath operation

    Um, yeah. But you haven't said why you commented it out. From what I remember about NSTask, that line would have set things up so your existing tool would work.

    —Jens
previous month july 2012 next month
MTWTFSS
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
Go to today