Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions opal/mca/installdirs/base/installdirs_base_components.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,93 @@
#include "opal/mca/installdirs/base/base.h"
#include "opal/mca/installdirs/base/static-components.h"

#if defined(__FreeBSD__) || defined(__linux__) || defined(__sun)
#include <sys/stat.h>
#include <unistd.h>
#endif

opal_install_dirs_t opal_install_dirs = {0};

static int
get_executable_path(char *path, unsigned size)
{
#if defined(__FreeBSD__)
int path_mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
int rval = size;

if (sysctl(path_mib, 4, path, &rval, NULL, 0) != 0) {
rval = -1;
}

#elif defined(__linux__)
int rval = readlink("/proc/self/exe", path, size);

if (rval <= 0) {
return rval;
}

/* truncate path */
if ((unsigned)rval >= size) {
rval = size - 1;
}

path[rval] = '\0';

#elif defined(__sun)
const char *exename = getexecname();
int rval;

if (exename == NULL) {
return -1;
}

strncpy(path, exename, size - 1);

/* ensure that path is terminated with a null */
path[size - 1] = '\0';

rval = strlen(path);

#elif defined(BUILD_OS_DARWIN)
uint32_t path_size = size;
int rval;

if (_NSGetExecutablePath(path, &path_size) < 0 || path_size < 1) {
return -1;
}

rval = (int)path_size - 1;

#else
int rval = -1;
#endif

return rval;
}


static void
directory_path(char *p)
{
char *s = strrchr(p, '/');
if (s == 0)
return;

*s = 0;
}


static int
get_executable_dir_path(char *buf, unsigned size)
{
int res = get_executable_path(buf, size);
if (res >= 0)
directory_path(buf);

return res;
}


#define CONDITIONAL_COPY(target, origin, field) \
do { \
if (origin.field != NULL && target.field == NULL) { \
Expand Down Expand Up @@ -83,6 +168,18 @@ opal_installdirs_base_open(mca_base_open_flag_t flags)
opalincludedir);
}

/* if prefix path does not exist then use path relative to executable */
{
struct stat s;
if (stat(opal_install_dirs.prefix, &s) != 0 || !S_ISDIR(s.st_mode)) {
char exe_path[255];
int res = get_executable_dir_path(exe_path, sizeof(exe_path));
if (res >= 0) {
asprintf(&opal_install_dirs.prefix, "%s/..", exe_path);
}
}
}

/* expand out all the fields */
opal_install_dirs.prefix =
opal_install_dirs_expand_setup(opal_install_dirs.prefix);
Expand Down
3 changes: 2 additions & 1 deletion opal/tools/wrappers/opal_wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,8 @@ data_callback(const char *key, const char *value)
} else if (0 == strcmp(key, "language")) {
if (NULL != value) options_data[parse_options_idx].language = strdup(value);
} else if (0 == strcmp(key, "compiler")) {
if (NULL != value) options_data[parse_options_idx].compiler = strdup(value);
if (NULL != value) options_data[parse_options_idx].compiler =
opal_install_dirs_expand(value);
} else if (0 == strcmp(key, "project")) {
if (NULL != value) options_data[parse_options_idx].project = strdup(value);
} else if (0 == strcmp(key, "version")) {
Expand Down