Esempio n. 1
0
char *__PHYSFS_platformCalcBaseDir(const char *argv0)
{
    char *retval = NULL;
    char *envr = NULL;

    /* fast path: default behaviour can handle this. */
    if ( (argv0 != NULL) && (strchr(argv0, '/') != NULL) )
        return(NULL);  /* higher level will parse out real path from argv0. */

    /*
     * Try to avoid using argv0 unless forced to. If there's a Linux-like
     *  /proc filesystem, you can get the full path to the current process from
     *  the /proc/self/exe symlink.
     */
    retval = readSymLink("/proc/self/exe");
    if (retval == NULL)
    {
        /* older kernels don't have /proc/self ... try PID version... */
        const unsigned long long pid = (unsigned long long) getpid();
        char path[64];
        const int rc = (int) snprintf(path,sizeof(path),"/proc/%llu/exe",pid);
        if ( (rc > 0) && (rc < sizeof(path)) )
            retval = readSymLink(path);
    } /* if */

    if (retval != NULL)  /* chop off filename. */
    {
        char *ptr = strrchr(retval, '/');
        if (ptr != NULL)
            *ptr = '\0';
    } /* if */

    if ((retval == NULL) && (argv0 != NULL))
    {
        /* If there's no dirsep on argv0, then look through $PATH for it. */
        envr = __PHYSFS_platformCopyEnvironmentVariable("PATH");
        BAIL_IF_MACRO(!envr, NULL, NULL);
        retval = findBinaryInPath(argv0, envr);
        allocator.Free(envr);
    } /* if */

    if (retval != NULL)
    {
        /* try to shrink buffer... */
        char *ptr = (char *) allocator.Realloc(retval, strlen(retval) + 1);
        if (ptr != NULL)
            retval = ptr;  /* oh well if it failed. */
    } /* if */

    return(retval);
} /* __PHYSFS_platformCalcBaseDir */
Esempio n. 2
0
char *__PHYSFS_platformCalcBaseDir(const char *argv0)
{
    char *retval = NULL;
    const char *envr = NULL;

    /* Try to avoid using argv0 unless forced to. Try system-specific stuff. */
    
    #if PHYSFS_PLATFORM_FREEBSD
    {
        char fullpath[PATH_MAX];
        size_t buflen = sizeof (fullpath);
        int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
        if (sysctl(mib, 4, fullpath, &buflen, NULL, 0) != -1)
            retval = __PHYSFS_strdup(fullpath);
    }
    #elif PHYSFS_PLATFORM_SOLARIS
    {
        const char *path = getexecname();
        if ((path != NULL) && (path[0] == '/'))  /* must be absolute path... */
            retval = __PHYSFS_strdup(path);
    }
    #endif

    if (retval)
        return retval;   /* already got it. */

    /* If there's a Linux-like /proc filesystem, you can get the full path to
     *  the current process from a symlink in there.
     */

    if (access("/proc", F_OK) == 0)
    {
        retval = readSymLink("/proc/self/exe");
        if (!retval) retval = readSymLink("/proc/curproc/file");
        if (!retval) retval = readSymLink("/proc/curproc/exe");
        if (retval == NULL)
        {
            /* older kernels don't have /proc/self ... try PID version... */
            const unsigned long long pid = (unsigned long long) getpid();
            char path[64];
            const int rc = (int) snprintf(path,sizeof(path),"/proc/%llu/exe",pid);
            if ( (rc > 0) && (rc < sizeof(path)) )
                retval = readSymLink(path);
        } /* if */
    } /* if */

    if (retval != NULL)  /* chop off filename. */
    {
        char *ptr = strrchr(retval, '/');
        if (ptr != NULL)
            *(ptr+1) = '\0';
        else  /* shouldn't happen, but just in case... */
        {
            physfs_alloc.Free(retval);
            retval = NULL;
        } /* else */
    } /* if */

    /* No /proc/self/exe, etc, but we have an argv[0] we can parse? */
    if ((retval == NULL) && (argv0 != NULL))
    {
        /* fast path: default behaviour can handle this. */
        if (strchr(argv0, '/') != NULL)
            return NULL;  /* higher level parses out real path from argv0. */

        /* If there's no dirsep on argv0, then look through $PATH for it. */
        envr = getenv("PATH");
        if (envr != NULL)
        {
            char *path = (char *) __PHYSFS_smallAlloc(strlen(envr) + 1);
            BAIL_IF_MACRO(!path, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
            strcpy(path, envr);
            retval = findBinaryInPath(argv0, path);
            __PHYSFS_smallFree(path);
        } /* if */
    } /* if */

    if (retval != NULL)
    {
        /* try to shrink buffer... */
        char *ptr = (char *) physfs_alloc.Realloc(retval, strlen(retval) + 1);
        if (ptr != NULL)
            retval = ptr;  /* oh well if it failed. */
    } /* if */

    return retval;
} /* __PHYSFS_platformCalcBaseDir */