File::currentExecutableFile for shared libraries fix


When the File::getSpecialLocation is used in a plugin shared library, most of the time the currentExecutable filename doesn’t exists, as the juce_setCurrentExecutableFileName function is not called cause we don’t have the command line arguments to correctly determine the name of the app.

in juce_linux_Files.cpp:

const File File::getSpecialLocation (const SpecialLocationType type)
    switch (type)
    case userHomeDirectory:
        const char* homeDir = getenv ("HOME");

        if (homeDir == 0)
            struct passwd* const pw = getpwuid (getuid());
            if (pw != 0)
                homeDir = pw->pw_dir;

        return File (String::fromUTF8 ((const uint8*) homeDir));

    case userDocumentsDirectory:
    case userMusicDirectory:
    case userMoviesDirectory:
    case userApplicationDataDirectory:
        return File ("~");

    case userDesktopDirectory:
        return File ("~/Desktop");

    case commonApplicationDataDirectory:
        return File ("/var");

    case globalApplicationsDirectory:
        return File ("/usr");

    case tempDirectory:
        File tmp ("/var/tmp");

        if (! tmp.isDirectory())
            tmp = T("/tmp");

            if (! tmp.isDirectory())
                tmp = File::getCurrentWorkingDirectory();

        return tmp;

    case currentExecutableFile:
    case currentApplicationFile:
        // try to obtain info from dladdr (as this could be a shared library !)
        if (! executableFile.exists())
            Dl_info executableInfo;
            dladdr ((const void*) juce_getFileTimes, &executableInfo);

            if (executableInfo.dli_fname != 0)
                executableFile = File (String (executableInfo.dli_fname));

        // if this fails, it's probably because juce_setCurrentExecutableFileName()
        // was never called to set the filename - this should be done by the juce
        // main() function, so maybe you've hacked it to use your own custom main()?
        jassert (executableFile.exists());

        return executableFile;

        jassertfalse // unknown type?

    return File::nonexistent;

obviously we need to include:

#include <dlfcn.h>

on the top of the file.

now doing a query of the currentExecutableFile inside plugins works as expected !!


Ah! Cunning stuff. Thanks kraken!