
* Installation directories will be inferred from the actual location of the shared library that contains the component. * OPAL_PREFIX and other environment variables allow users to override the inferred directories. They should no longer be necessary in most cases, though. * Any directories that cannot be inferred will fall back to whatever is provided by the config installdirs component. This commit was SVN r21723.
182 строки
5.4 KiB
C
182 строки
5.4 KiB
C
/* -*- Mode: C; c-basic-offset:4 ; -*- */
|
|
/*
|
|
* Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved.
|
|
*
|
|
* $COPYRIGHT$
|
|
*
|
|
* Additional copyrights may follow
|
|
*
|
|
* $HEADER$
|
|
*
|
|
* This module automatically detects the path to itself, and
|
|
* instructs the base install_dirs module to infer the prefix
|
|
* from that.
|
|
*/
|
|
|
|
#include "opal_config.h"
|
|
|
|
#include "opal/constants.h"
|
|
#include "opal/mca/mca.h"
|
|
#include "opal/mca/installdirs/installdirs.h"
|
|
#include "opal/util/basename.h"
|
|
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
|
|
int opal_installdirs_autodetect_open(void);
|
|
|
|
opal_installdirs_base_component_t mca_installdirs_autodetect_component = {
|
|
/* First, the mca_component_t struct containing meta information
|
|
about the component itself */
|
|
{
|
|
OPAL_INSTALLDIRS_BASE_VERSION_2_0_0,
|
|
|
|
/* Component name and version */
|
|
"autodetect",
|
|
OPAL_MAJOR_VERSION,
|
|
OPAL_MINOR_VERSION,
|
|
OPAL_RELEASE_VERSION,
|
|
|
|
/* Component open and close functions */
|
|
opal_installdirs_autodetect_open,
|
|
NULL
|
|
},
|
|
{
|
|
/* This component is Checkpointable */
|
|
MCA_BASE_METADATA_PARAM_CHECKPOINT
|
|
}
|
|
};
|
|
|
|
/*
|
|
* Determine whether the load object is an executable or a shared library.
|
|
* The code only works for ELF files. The values and offsets are cribbed
|
|
* from the "file" command's magic number file.
|
|
*/
|
|
|
|
typedef enum { executable, shared_object, unknown_object } load_obj_t;
|
|
|
|
static load_obj_t
|
|
whatis(const char *path)
|
|
{
|
|
int fd;
|
|
char buf[18];
|
|
uint16_t *kind;
|
|
|
|
fd = open(path, O_RDONLY);
|
|
if (fd < 0) {
|
|
return unknown_object;
|
|
}
|
|
|
|
if (read(fd, buf, sizeof(buf)) < sizeof(buf)) {
|
|
close(fd);
|
|
return unknown_object;
|
|
}
|
|
close(fd);
|
|
|
|
if (strncmp(buf, "\177ELF", 4) != 0) {
|
|
return unknown_object;
|
|
}
|
|
|
|
kind = (uint16_t*)&buf[16];
|
|
if (2 == *kind) {
|
|
return executable;
|
|
} else if (3 == *kind) {
|
|
return shared_object;
|
|
} else {
|
|
return unknown_object;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* OS-dependent function to get the address of some instruction in
|
|
* this module. We cannot in general just do &func, because if the
|
|
* module is in a shared library that can return some other address.
|
|
* (On Solaris, for example, it will return the address of an entry in
|
|
* the PLT of the program, rather than the shared library.)
|
|
*/
|
|
|
|
uintptr_t opal_installdirs_autodetect_pc(void);
|
|
|
|
/*
|
|
* OS-dependent function to find the path to the executable or shared
|
|
* library that contains the given address in the process' address
|
|
* space.
|
|
*/
|
|
|
|
const char *opal_installdirs_autodetect_path(uintptr_t);
|
|
|
|
static int
|
|
opal_installdirs_autodetect_open(void)
|
|
{
|
|
uintptr_t my_addr;
|
|
const char *path;
|
|
const char *my_dir;
|
|
const char *infer_from;
|
|
|
|
if (getenv("OPAL_DESTDIR") != NULL) {
|
|
/*
|
|
* OPAL_DESTDIR does not play well with autodetect. We
|
|
* certainly don't want it to be used as a prefix for the actual
|
|
* installed path. We could try to inhibit it only for those
|
|
* paths that cannot be inferred from the actual installed
|
|
* path, but it is simpler just to assume the user wants no
|
|
* auto detection if OPAL_DESTDIR is set.
|
|
*/
|
|
return OPAL_ERR_NOT_FOUND;
|
|
}
|
|
|
|
my_addr = opal_installdirs_autodetect_pc();
|
|
if (0 == my_addr) {
|
|
return OPAL_ERR_NOT_FOUND;
|
|
}
|
|
path = opal_installdirs_autodetect_path(my_addr);
|
|
if (NULL == path) {
|
|
return OPAL_ERR_NOT_FOUND;
|
|
}
|
|
my_dir = opal_dirname(path);
|
|
if (NULL == my_dir) {
|
|
free(path);
|
|
return OPAL_ERR_NOT_FOUND;
|
|
}
|
|
switch(whatis(path)) {
|
|
case executable:
|
|
mca_installdirs_autodetect_component.install_dirs_data.bindir = my_dir;
|
|
infer_from = "${infer-bindir}";
|
|
mca_installdirs_autodetect_component.install_dirs_data.libdir = infer_from;
|
|
break;
|
|
case shared_object:
|
|
mca_installdirs_autodetect_component.install_dirs_data.libdir = my_dir;
|
|
infer_from = "${infer-libdir}";
|
|
mca_installdirs_autodetect_component.install_dirs_data.bindir = infer_from;
|
|
break;
|
|
default:
|
|
free(my_dir);
|
|
free(path);
|
|
return OPAL_ERR_NOT_FOUND;
|
|
break;
|
|
}
|
|
free(path);
|
|
|
|
mca_installdirs_autodetect_component.install_dirs_data.prefix = infer_from;
|
|
mca_installdirs_autodetect_component.install_dirs_data.exec_prefix = infer_from;
|
|
mca_installdirs_autodetect_component.install_dirs_data.sbindir = infer_from;
|
|
mca_installdirs_autodetect_component.install_dirs_data.libexecdir = infer_from;
|
|
mca_installdirs_autodetect_component.install_dirs_data.datarootdir = infer_from;
|
|
mca_installdirs_autodetect_component.install_dirs_data.datadir = infer_from;
|
|
mca_installdirs_autodetect_component.install_dirs_data.sysconfdir = infer_from;
|
|
mca_installdirs_autodetect_component.install_dirs_data.sharedstatedir = infer_from;
|
|
mca_installdirs_autodetect_component.install_dirs_data.localstatedir = infer_from;
|
|
mca_installdirs_autodetect_component.install_dirs_data.includedir = infer_from;
|
|
mca_installdirs_autodetect_component.install_dirs_data.infodir = infer_from;
|
|
mca_installdirs_autodetect_component.install_dirs_data.mandir = infer_from;
|
|
mca_installdirs_autodetect_component.install_dirs_data.pkgdatadir = infer_from;
|
|
mca_installdirs_autodetect_component.install_dirs_data.pkglibdir = infer_from;
|
|
mca_installdirs_autodetect_component.install_dirs_data.pkgincludedir = infer_from;
|
|
|
|
return OPAL_SUCCESS;
|
|
}
|
|
|