File::getSpecialLocation(File::currentExecutableFile)

Jules,

I just got bitten up the ass by the fact that this case, and by extension, currentApplicationFile, are not implemented under linux.

I don’t know if you are aware of this, but you can generally get the current exe by resolving the symlink

/proc//exe

where pid is the pid of the running application.

I’ll try and knock together some code this weekend, but if I get sidetracked (highly probable) there is at least something for you to work from, if you weren’t already familiar with that trick.

Edit: pissing around with the pid is pretty pointless when you can just use the ‘self’ process dependent symlink - guaranteed to be linuxthreads friendly too.

I had a spare 15 minutes, so I knocked this out:


    case currentExecutableFile:
    {
        bool bufferTooSmall = true;
        int bufferSize = 0;
        int returnCode;
        File tmp;
        while (bufferTooSmall)
        {
             bufferSize = bufferSize + 64;
             char buffer[bufferSize];
             for (int i = bufferSize - 64; i < bufferSize; i ++)
                     buffer[i] = 0;
             returnCode = readlink("/proc/self/exe\0", buffer, bufferSize);
             if (returnCode != EFAULT)
             {
                tmp = File(String(buffer));
                bufferTooSmall = false;
             }
        }
        return tmp;
    }

It works, but it’s hardly efficient.

Feel free to do whatever with it.

Hi Valley

…but it does work under linux, doesn’t it? When the app starts, it calls juce_setCurrentExecutableFileName() using the path from argv, and that’s what it returns later on. Doesn’t this work on your system?

If you let me know where it’s failing, maybe we can add your code as a fallback plan where the normal method doesn’t do its job…

[quote=“jules”]Hi Valley

…but it does work under linux, doesn’t it? When the app starts, it calls juce_setCurrentExecutableFileName() using the path from argv, and that’s what it returns later on. Doesn’t this work on your system?[/quote]

On my system I get an empty string back from that method. Under Win/Mac everything works as expected, but under linux, just a String::empty.

I’ll make sure I have the latest build installed, although I only downloaded it this week, so I shoudl have. :?

[quote]
If you let me know where it’s failing, maybe we can add your code as a fallback plan where the normal method doesn’t do its job…[/quote]

I’ll take another look at JUCE’s code and see if I can see where it is failing. Although it should never make any difference under linux, the code I was working on is command line app, so I’m using the command line only macros. Perhaps that’s confusing things.

I’d have still expected it to work. Best plan would be to shoehorn your code in there if it has an empty string. Might be some kind of difference between the way distros pass arguments to an app.

ok, I’m being a muppet.

Because this is a command line app, and because I need it to be a command line under windows too, I’m not making my app a subclass of JUCEApplication. Rather I’m using my own main(). This defeats the call to setCurrentExecutable on linux, and is why I was running into problems.

I’ve modified my code above to check for a non-existant file before grabbing the file name from the /proc/ space. I don’t know if this will be an issue for others, as in most cases it isn’t necessary to avoid JUCEApplication on windows. I ran into some specific issues that forced me to do that.

Ok, well it’s a handy code snippet to have anyway!

I’ll add an assertion to catch other people who might do this, and to explain what’s going in.