Added autodetect installdirs component. Currently supports Solaris and Linux.
* 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.
Этот коммит содержится в:
родитель
b3e0c79275
Коммит
2250be582d
1
AUTHORS
1
AUTHORS
@ -32,6 +32,7 @@ gwatson Greg Watson LANL
|
|||||||
herault Thomas Herault INRIA
|
herault Thomas Herault INRIA
|
||||||
hpcstork Sven Stork HLRS
|
hpcstork Sven Stork HLRS
|
||||||
htor Torsten Hoefler IU, TUC
|
htor Torsten Hoefler IU, TUC
|
||||||
|
igb Iain Bason Sun
|
||||||
jdmason Jon Mason Chelsio
|
jdmason Jon Mason Chelsio
|
||||||
jjhursey Josh Hursey IU, ORNL, LANL, LBNL
|
jjhursey Josh Hursey IU, ORNL, LANL, LBNL
|
||||||
jnysal Nysal Jan IBM
|
jnysal Nysal Jan IBM
|
||||||
|
7
NEWS
7
NEWS
@ -10,7 +10,7 @@ Copyright (c) 2004-2006 The Regents of the University of California.
|
|||||||
All rights reserved.
|
All rights reserved.
|
||||||
Copyright (c) 2006-2009 Cisco Systems, Inc. All rights reserved.
|
Copyright (c) 2006-2009 Cisco Systems, Inc. All rights reserved.
|
||||||
Copyright (c) 2006 Voltaire, Inc. All rights reserved.
|
Copyright (c) 2006 Voltaire, Inc. All rights reserved.
|
||||||
Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
|
Copyright (c) 2006-2009 Sun Microsystems, Inc. All rights reserved.
|
||||||
Use is subject to license terms.
|
Use is subject to license terms.
|
||||||
Copyright (c) 2006-2007 Los Alamos National Security, LLC. All rights
|
Copyright (c) 2006-2007 Los Alamos National Security, LLC. All rights
|
||||||
reserved.
|
reserved.
|
||||||
@ -32,6 +32,11 @@ Trunk (not on release branches yet)
|
|||||||
- Added Cray Compute Node Linux (CNL) and ALPS Support.
|
- Added Cray Compute Node Linux (CNL) and ALPS Support.
|
||||||
--> Expected: ???
|
--> Expected: ???
|
||||||
|
|
||||||
|
- Added automatic detection of installation directories for
|
||||||
|
Solaris and Linux. The OPAL_PREFIX and OPAL_DESTDIR
|
||||||
|
environment variables no longer need to be set when binaries
|
||||||
|
are installed in non-default locations.
|
||||||
|
|
||||||
1.5
|
1.5
|
||||||
---
|
---
|
||||||
|
|
||||||
|
26
opal/mca/installdirs/autodetect/Makefile.am
Обычный файл
26
opal/mca/installdirs/autodetect/Makefile.am
Обычный файл
@ -0,0 +1,26 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved.
|
||||||
|
# $COPYRIGHT$
|
||||||
|
#
|
||||||
|
# Additional copyrights may follow
|
||||||
|
#
|
||||||
|
# $HEADER$
|
||||||
|
#
|
||||||
|
|
||||||
|
noinst_LTLIBRARIES = libmca_installdirs_autodetect.la
|
||||||
|
|
||||||
|
libmca_installdirs_autodetect_la_SOURCES = opal_installdirs_autodetect_component.c
|
||||||
|
|
||||||
|
EXTRA_libmca_installdirs_autodetect_la_SOURCES = \
|
||||||
|
opal_installdirs_solaris.c \
|
||||||
|
opal_installdirs_linux.c \
|
||||||
|
opal_installdirs_backtrace.c \
|
||||||
|
opal_installdirs_walkcontext.c
|
||||||
|
|
||||||
|
libmca_installdirs_autodetect_la_LIBADD = \
|
||||||
|
$(OMPI_INSTALLDIRS_AUTODETECT_PATH) \
|
||||||
|
$(OMPI_INSTALLDIRS_AUTODETECT_PC)
|
||||||
|
|
||||||
|
libmca_installdirs_autodetect_la_DEPENDENCIES = \
|
||||||
|
$(OMPI_INSTALLDIRS_AUTODETECT_PATH) \
|
||||||
|
$(OMPI_INSTALLDIRS_AUTODETECT_PC)
|
65
opal/mca/installdirs/autodetect/configure.m4
Обычный файл
65
opal/mca/installdirs/autodetect/configure.m4
Обычный файл
@ -0,0 +1,65 @@
|
|||||||
|
# -*- shell-script -*-
|
||||||
|
#
|
||||||
|
# Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved.
|
||||||
|
# $COPYRIGHT$
|
||||||
|
#
|
||||||
|
# Additional copyrights may follow
|
||||||
|
#
|
||||||
|
# $HEADER$
|
||||||
|
#
|
||||||
|
|
||||||
|
AC_DEFUN([MCA_installdirs_autodetect_COMPILE_MODE], [
|
||||||
|
AC_MSG_CHECKING([for MCA component $2:$3 compile mode])
|
||||||
|
$4="static"
|
||||||
|
AC_MSG_RESULT([$$4])
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# MCA_installdirs_autodetect_CONFIG(action-if-can-compile,
|
||||||
|
# [action-if-cant-compile])
|
||||||
|
# ------------------------------------------------
|
||||||
|
#
|
||||||
|
# Solaris uses a binary-format /proc/$$/map file that contains a
|
||||||
|
# sequence of prmap_t structures. Those can be used to look up
|
||||||
|
# associated files in /proc/$$/path, which are symbolic links to
|
||||||
|
# the actual files.
|
||||||
|
#
|
||||||
|
# AIX has /proc/$$/map and /proc/$$/object, but no /proc/$$/path.
|
||||||
|
# I don't know how to achieve autodetect functionality on AIX.
|
||||||
|
#
|
||||||
|
# Linux has /proc/self/maps that contains text with both virtual
|
||||||
|
# addresses and paths. (Under Linux 2.0 there are no paths. I
|
||||||
|
# don't know how to achieve autodetect functionality on such
|
||||||
|
# systems.)
|
||||||
|
|
||||||
|
AC_DEFUN([MCA_installdirs_autodetect_CONFIG],[
|
||||||
|
AC_CHECK_HEADERS(procfs.h,
|
||||||
|
[AC_CHECK_FILE(/proc/$$/path,
|
||||||
|
[procfs_path_happy="yes"
|
||||||
|
OMPI_INSTALLDIRS_AUTODETECT_PATH=opal_installdirs_solaris.lo],
|
||||||
|
[procfs_path_happy="no"])],
|
||||||
|
[AC_CHECK_FILE(/proc/self/maps,
|
||||||
|
[procfs_path_happy="yes"
|
||||||
|
OMPI_INSTALLDIRS_AUTODETECT_PATH=opal_installdirs_linux.lo],
|
||||||
|
[procfs_path_happy="no"])])
|
||||||
|
|
||||||
|
AS_IF([test "$procfs_path_happy" = "yes"],[
|
||||||
|
# The following check is from opal/mca/backtrace/execinfo/configure.m4
|
||||||
|
AC_CHECK_HEADERS([execinfo.h],[
|
||||||
|
# FreeBSD has backtrace in -lexecinfo, usually in libc
|
||||||
|
OMPI_CHECK_FUNC_LIB([backtrace], [execinfo],
|
||||||
|
[findpc_happy="yes"
|
||||||
|
OMPI_INSTALLDIRS_AUTODETECT_PC=opal_installdirs_backtrace.lo],
|
||||||
|
[findpc_happy="no"])])
|
||||||
|
|
||||||
|
AS_IF([test "$backtrace_execinfo_happy" = "no"],[
|
||||||
|
AC_CHECK_HEADERS([ucontext.h],[
|
||||||
|
OMPI_CHECK_FUNC_LIB([walkcontext],,
|
||||||
|
[findpc_happy="yes"
|
||||||
|
OMPI_INSTALLDIRS_AUTODETECT_PC=opal_installdirs_walkcontext.lo],
|
||||||
|
[findpc_happy="no"])])])])
|
||||||
|
|
||||||
|
AS_IF([test "$procfs_path_happy" = "yes" -a "$findpc_happy" = "yes"],[
|
||||||
|
AC_SUBST([OMPI_INSTALLDIRS_AUTODETECT_PATH])
|
||||||
|
AC_SUBST([OMPI_INSTALLDIRS_AUTODETECT_PC])
|
||||||
|
$1],[$2])])
|
15
opal/mca/installdirs/autodetect/configure.params
Обычный файл
15
opal/mca/installdirs/autodetect/configure.params
Обычный файл
@ -0,0 +1,15 @@
|
|||||||
|
# -*- shell-script -*-
|
||||||
|
#
|
||||||
|
# Copyright (c) 2006 Los Alamos National Security, LLC. All rights
|
||||||
|
# reserved.
|
||||||
|
# $COPYRIGHT$
|
||||||
|
#
|
||||||
|
# Additional copyrights may follow
|
||||||
|
#
|
||||||
|
# $HEADER$
|
||||||
|
#
|
||||||
|
|
||||||
|
# Specific to this module
|
||||||
|
|
||||||
|
PARAM_CONFIG_PRIORITY=5
|
||||||
|
PARAM_CONFIG_FILES="Makefile"
|
@ -0,0 +1,181 @@
|
|||||||
|
/* -*- 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;
|
||||||
|
}
|
||||||
|
|
23
opal/mca/installdirs/autodetect/opal_installdirs_backtrace.c
Обычный файл
23
opal/mca/installdirs/autodetect/opal_installdirs_backtrace.c
Обычный файл
@ -0,0 +1,23 @@
|
|||||||
|
/* -*- Mode: C; c-basic-offset:4 ; -*- */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "opal_config.h"
|
||||||
|
|
||||||
|
#include <execinfo.h>
|
||||||
|
|
||||||
|
uintptr_t
|
||||||
|
opal_installdirs_autodetect_pc()
|
||||||
|
{
|
||||||
|
void *pc = 0;
|
||||||
|
|
||||||
|
backtrace(&pc, 1);
|
||||||
|
return pc;
|
||||||
|
}
|
188
opal/mca/installdirs/autodetect/opal_installdirs_linux.c
Обычный файл
188
opal/mca/installdirs/autodetect/opal_installdirs_linux.c
Обычный файл
@ -0,0 +1,188 @@
|
|||||||
|
/* -*- Mode: C; c-basic-offset:4 ; -*- */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*
|
||||||
|
* Read /proc/self/maps to find the path to the file containing
|
||||||
|
* an address.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "opal_config.h"
|
||||||
|
#include "opal_stdint.h"
|
||||||
|
|
||||||
|
#include "opal/constants.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
uintptr_t read_addr(FILE *);
|
||||||
|
int skip_fields(FILE *, int);
|
||||||
|
int read_path(FILE *);
|
||||||
|
int skip_line(FILE *);
|
||||||
|
|
||||||
|
const char *
|
||||||
|
opal_installdirs_autodetect_path(uintptr_t my_addr)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
uintptr_t lo_start, lo_end;
|
||||||
|
|
||||||
|
f = fopen("/proc/self/maps", "r");
|
||||||
|
if (NULL == f) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
lo_start = read_addr(f);
|
||||||
|
if (0 == lo_start) {
|
||||||
|
fclose(f);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
lo_end = read_addr(f);
|
||||||
|
if (0 == lo_end) {
|
||||||
|
fclose(f);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (lo_start <= my_addr && lo_end > my_addr) {
|
||||||
|
const char *path, *my_dir;
|
||||||
|
int e = skip_fields(f, 4);
|
||||||
|
if (OPAL_SUCCESS != e) {
|
||||||
|
fclose(f);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
path = read_path(f);
|
||||||
|
fclose(f);
|
||||||
|
return path;
|
||||||
|
} else {
|
||||||
|
int e = skip_line(f);
|
||||||
|
if (OPAL_SUCCESS != e) {
|
||||||
|
fclose(f);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following routines don't use isspace et al, because we don't
|
||||||
|
* want the locale setting to influence them.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read a hex address from a file. We don't know how many
|
||||||
|
* digits there will be. We only know that the result will
|
||||||
|
* fit into a uintptr_t, and will not be zero.
|
||||||
|
*
|
||||||
|
* Return zero on error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static uintptr_t
|
||||||
|
read_addr(FILE *f)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
uintptr_t n = 0;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
c = getc(f);
|
||||||
|
if (EOF == c) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (' ' == c || '-' == c) {
|
||||||
|
if (n > 0) {
|
||||||
|
return n;
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (c >= '0' && c <= '9') {
|
||||||
|
n <<= 4;
|
||||||
|
n += c - '0';
|
||||||
|
} else if (c >= 'a' && c <= 'f') {
|
||||||
|
n <<= 4;
|
||||||
|
n += c - 'a' + 10;
|
||||||
|
} else if (c >= 'A' && c <= 'F') {
|
||||||
|
n <<= 4;
|
||||||
|
n += c - 'A' + 10;
|
||||||
|
} else {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Skip n fields of input, where fields are separated by white space.
|
||||||
|
*
|
||||||
|
* Return OPAL_SUCCESS on success.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
skip_fields(FILE *f, int n)
|
||||||
|
{
|
||||||
|
int c = getc(f);
|
||||||
|
while (n-- > 0) {
|
||||||
|
for (; c == ' ' || c == '\t'; c = getc(f));
|
||||||
|
if (c == EOF || c == '\n') {
|
||||||
|
return OPAL_ERR_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
for(; c != ' ' && c != '\t' && c != '\n'; c = getc(f));
|
||||||
|
}
|
||||||
|
return OPAL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read a path, and return it. Return NULL on error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
read_path(FILE *f)
|
||||||
|
{
|
||||||
|
char *path = malloc(100);
|
||||||
|
int n = 100;
|
||||||
|
int i = 0;
|
||||||
|
int c = getc(f);
|
||||||
|
|
||||||
|
for (; (c == ' ' || c == '\t') && c != '\n' && c != EOF; c = getc(f));
|
||||||
|
for (; c != '\n' && EOF != c; c = getc(f)) {
|
||||||
|
if (i >= n) {
|
||||||
|
n += 100;
|
||||||
|
path = realloc(path, n);
|
||||||
|
}
|
||||||
|
if (NULL == path) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
path[i++] = c;
|
||||||
|
}
|
||||||
|
if (i >= n) {
|
||||||
|
n++;
|
||||||
|
path = realloc(path, n);
|
||||||
|
} else {
|
||||||
|
path = realloc(path, i + 1);
|
||||||
|
}
|
||||||
|
if (NULL == path) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
path[i] = '\0';
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Skip to the next line of input. Return OPAL_SUCCESS on success.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
skip_line(FILE *f)
|
||||||
|
{
|
||||||
|
int c = 0;
|
||||||
|
while (c != '\n') {
|
||||||
|
c = getc(f);
|
||||||
|
if (EOF == c) {
|
||||||
|
return OPAL_ERR_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return OPAL_SUCCESS;
|
||||||
|
}
|
91
opal/mca/installdirs/autodetect/opal_installdirs_solaris.c
Обычный файл
91
opal/mca/installdirs/autodetect/opal_installdirs_solaris.c
Обычный файл
@ -0,0 +1,91 @@
|
|||||||
|
/* -*- Mode: C; c-basic-offset:4 ; -*- */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*
|
||||||
|
* Read /proc/<pid>/map and /proc/<pid>/path to find the file mapped
|
||||||
|
* into the process over the given address.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "opal_config.h"
|
||||||
|
#include "opal_stdint.h"
|
||||||
|
|
||||||
|
#include "opal/constants.h"
|
||||||
|
|
||||||
|
#include <procfs.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
const char *
|
||||||
|
opal_installdirs_autodetect_path(uintptr_t my_addr)
|
||||||
|
{
|
||||||
|
pid_t my_pid;
|
||||||
|
char *map_path;
|
||||||
|
prmap_t map;
|
||||||
|
int map_fd;
|
||||||
|
char *obj_name;
|
||||||
|
ssize_t path_size, ls;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
my_pid = getpid();
|
||||||
|
asprintf(&map_path, "/proc/%d/map", my_pid);
|
||||||
|
if (NULL == map_path) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
map_fd = open(map_path, O_RDONLY);
|
||||||
|
free(map_path);
|
||||||
|
if (map_fd < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (read(map_fd, &map, sizeof(map)) < sizeof(map)) {
|
||||||
|
return OPAL_ERR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
if (map.pr_vaddr <= my_addr && map.pr_vaddr + map.pr_size > my_addr) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(map_fd);
|
||||||
|
asprintf(&obj_name, "/proc/%d/path/%s", my_pid, map.pr_mapname);
|
||||||
|
if (NULL == obj_name) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
We don't know how long the path to the load object might be.
|
||||||
|
Try allocating a reasonable length. If the readlink system
|
||||||
|
call doesn't use the entire buffer passed to it then we know
|
||||||
|
the path is complete.
|
||||||
|
*/
|
||||||
|
for (path_size = 100; ; path_size += 100) {
|
||||||
|
path = malloc(path_size);
|
||||||
|
if (NULL == path) {
|
||||||
|
free(obj_name);
|
||||||
|
return OPAL_ERR_OUT_OF_RESOURCE;
|
||||||
|
}
|
||||||
|
ls = readlink(obj_name, path, path_size);
|
||||||
|
if (ls < 0) {
|
||||||
|
free(obj_name);
|
||||||
|
free(path);
|
||||||
|
return OPAL_ERR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
if (ls < path_size) {
|
||||||
|
path[ls] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(obj_name);
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
34
opal/mca/installdirs/autodetect/opal_installdirs_walkcontext.c
Обычный файл
34
opal/mca/installdirs/autodetect/opal_installdirs_walkcontext.c
Обычный файл
@ -0,0 +1,34 @@
|
|||||||
|
/* -*- Mode: C; c-basic-offset:4 ; -*- */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "opal_config.h"
|
||||||
|
|
||||||
|
#include <ucontext.h>
|
||||||
|
|
||||||
|
static int
|
||||||
|
savepc(uintptr_t pc, int sig, void *storage)
|
||||||
|
{
|
||||||
|
*(uintptr_t*)storage = pc;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t
|
||||||
|
opal_installdirs_autodetect_pc()
|
||||||
|
{
|
||||||
|
ucontext_t ctx;
|
||||||
|
uintptr_t value = 0;
|
||||||
|
|
||||||
|
if (getcontext(&ctx) == -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
walkcontext(&ctx, savepc, &value);
|
||||||
|
return value;
|
||||||
|
}
|
@ -1,11 +1,12 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2007 Los Alamos National Security, LLC. All rights
|
* Copyright (c) 2006-2007 Los Alamos National Security, LLC. All rights
|
||||||
* reserved.
|
* reserved.
|
||||||
* Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
|
* Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
|
||||||
|
* Copyright (c) 2009 Sun Microsystem, Inc. All rights reserved.
|
||||||
* $COPYRIGHT$
|
* $COPYRIGHT$
|
||||||
*
|
*
|
||||||
* Additional copyrights may follow
|
* Additional copyrights may follow
|
||||||
*
|
*
|
||||||
* $HEADER$
|
* $HEADER$
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -22,29 +23,59 @@ int opal_installdirs_base_output;
|
|||||||
opal_install_dirs_t opal_install_dirs;
|
opal_install_dirs_t opal_install_dirs;
|
||||||
opal_list_t opal_installdirs_components;
|
opal_list_t opal_installdirs_components;
|
||||||
|
|
||||||
#define CONDITIONAL_COPY(target, origin, field) \
|
char *
|
||||||
do { \
|
opal_install_dirs_infer(const char *inferred_field,
|
||||||
if (origin.field != NULL && target.field == NULL) { \
|
const char *infer_from_field,
|
||||||
target.field = origin.field; \
|
size_t infer_from_field_len,
|
||||||
} \
|
opal_install_dirs_t *component_installdirs);
|
||||||
} while (0)
|
|
||||||
|
/*
|
||||||
|
* There is a memory leak when inferring a field. The function
|
||||||
|
* opal_install_dirs_infer returns allocated memory. We will
|
||||||
|
* later call opal_install_dirs_expand for the field, which
|
||||||
|
* also allocates memory. We don't record which fields were
|
||||||
|
* inferred, so we don't know whether to call free after calling
|
||||||
|
* opal_install_dirs_expand.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CONDITIONAL_COPY(target, origin, field) \
|
||||||
|
do { \
|
||||||
|
if (origin.field != NULL) { \
|
||||||
|
if (NULL != target.field && \
|
||||||
|
strncmp(target.field, "${infer-", 8) == 0) { \
|
||||||
|
const char *fe = strchr(target.field, '}'); \
|
||||||
|
if (NULL != fe) { \
|
||||||
|
const char *f = target.field + 8; \
|
||||||
|
target.field = \
|
||||||
|
opal_install_dirs_infer(#field, f, fe - f, &origin); \
|
||||||
|
} else { \
|
||||||
|
target.field = NULL; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
if (NULL == target.field) { \
|
||||||
|
target.field = origin.field; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
} while (0) \
|
||||||
|
|
||||||
int
|
int
|
||||||
opal_installdirs_base_open(void)
|
opal_installdirs_base_open(void)
|
||||||
{
|
{
|
||||||
int i, ret;
|
int i, ret;
|
||||||
mca_base_component_list_item_t *cli;
|
mca_base_component_list_item_t *cli;
|
||||||
|
opal_install_dirs_t expanded_dirs;
|
||||||
|
|
||||||
OBJ_CONSTRUCT(&opal_installdirs_components, opal_list_t);
|
OBJ_CONSTRUCT(&opal_installdirs_components, opal_list_t);
|
||||||
for (i = 0 ; mca_installdirs_base_static_components[i] != NULL ; ++i) {
|
for (i = 0 ; mca_installdirs_base_static_components[i] != NULL ; ++i) {
|
||||||
opal_installdirs_base_component_t *component =
|
opal_installdirs_base_component_t *component =
|
||||||
(opal_installdirs_base_component_t*)
|
(opal_installdirs_base_component_t*)
|
||||||
mca_installdirs_base_static_components[i];
|
mca_installdirs_base_static_components[i];
|
||||||
|
|
||||||
/* Save it in a global list for ompi_info */
|
/* Save it in a global list for ompi_info */
|
||||||
cli = OBJ_NEW(mca_base_component_list_item_t);
|
cli = OBJ_NEW(mca_base_component_list_item_t);
|
||||||
cli->cli_component = mca_installdirs_base_static_components[i];
|
cli->cli_component = mca_installdirs_base_static_components[i];
|
||||||
opal_list_append(&opal_installdirs_components,
|
opal_list_append(&opal_installdirs_components,
|
||||||
&cli->super);
|
&cli->super);
|
||||||
|
|
||||||
if (NULL != component->component.mca_open_component) {
|
if (NULL != component->component.mca_open_component) {
|
||||||
@ -53,7 +84,7 @@ opal_installdirs_base_open(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* copy over the data, if something isn't already there */
|
/* copy over the data, if something isn't already there */
|
||||||
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
||||||
prefix);
|
prefix);
|
||||||
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
||||||
exec_prefix);
|
exec_prefix);
|
||||||
@ -67,63 +98,64 @@ opal_installdirs_base_open(void)
|
|||||||
datarootdir);
|
datarootdir);
|
||||||
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
||||||
datadir);
|
datadir);
|
||||||
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
||||||
sysconfdir);
|
sysconfdir);
|
||||||
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
||||||
sharedstatedir);
|
sharedstatedir);
|
||||||
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
||||||
localstatedir);
|
localstatedir);
|
||||||
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
||||||
libdir);
|
libdir);
|
||||||
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
||||||
includedir);
|
includedir);
|
||||||
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
||||||
infodir);
|
infodir);
|
||||||
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
||||||
mandir);
|
mandir);
|
||||||
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
||||||
pkgdatadir);
|
pkgdatadir);
|
||||||
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
||||||
pkglibdir);
|
pkglibdir);
|
||||||
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
CONDITIONAL_COPY(opal_install_dirs, component->install_dirs_data,
|
||||||
pkgincludedir);
|
pkgincludedir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* expand out all the fields */
|
/* expand out all the fields */
|
||||||
opal_install_dirs.prefix =
|
expanded_dirs.prefix =
|
||||||
opal_install_dirs_expand(opal_install_dirs.prefix);
|
opal_install_dirs_expand(opal_install_dirs.prefix);
|
||||||
opal_install_dirs.exec_prefix =
|
expanded_dirs.exec_prefix =
|
||||||
opal_install_dirs_expand(opal_install_dirs.exec_prefix);
|
opal_install_dirs_expand(opal_install_dirs.exec_prefix);
|
||||||
opal_install_dirs.bindir =
|
expanded_dirs.bindir =
|
||||||
opal_install_dirs_expand(opal_install_dirs.bindir);
|
opal_install_dirs_expand(opal_install_dirs.bindir);
|
||||||
opal_install_dirs.sbindir =
|
expanded_dirs.sbindir =
|
||||||
opal_install_dirs_expand(opal_install_dirs.sbindir);
|
opal_install_dirs_expand(opal_install_dirs.sbindir);
|
||||||
opal_install_dirs.libexecdir =
|
expanded_dirs.libexecdir =
|
||||||
opal_install_dirs_expand(opal_install_dirs.libexecdir);
|
opal_install_dirs_expand(opal_install_dirs.libexecdir);
|
||||||
opal_install_dirs.datarootdir =
|
expanded_dirs.datarootdir =
|
||||||
opal_install_dirs_expand(opal_install_dirs.datarootdir);
|
opal_install_dirs_expand(opal_install_dirs.datarootdir);
|
||||||
opal_install_dirs.datadir =
|
expanded_dirs.datadir =
|
||||||
opal_install_dirs_expand(opal_install_dirs.datadir);
|
opal_install_dirs_expand(opal_install_dirs.datadir);
|
||||||
opal_install_dirs.sysconfdir =
|
expanded_dirs.sysconfdir =
|
||||||
opal_install_dirs_expand(opal_install_dirs.sysconfdir);
|
opal_install_dirs_expand(opal_install_dirs.sysconfdir);
|
||||||
opal_install_dirs.sharedstatedir =
|
expanded_dirs.sharedstatedir =
|
||||||
opal_install_dirs_expand(opal_install_dirs.sharedstatedir);
|
opal_install_dirs_expand(opal_install_dirs.sharedstatedir);
|
||||||
opal_install_dirs.localstatedir =
|
expanded_dirs.localstatedir =
|
||||||
opal_install_dirs_expand(opal_install_dirs.localstatedir);
|
opal_install_dirs_expand(opal_install_dirs.localstatedir);
|
||||||
opal_install_dirs.libdir =
|
expanded_dirs.libdir =
|
||||||
opal_install_dirs_expand(opal_install_dirs.libdir);
|
opal_install_dirs_expand(opal_install_dirs.libdir);
|
||||||
opal_install_dirs.includedir =
|
expanded_dirs.includedir =
|
||||||
opal_install_dirs_expand(opal_install_dirs.includedir);
|
opal_install_dirs_expand(opal_install_dirs.includedir);
|
||||||
opal_install_dirs.infodir =
|
expanded_dirs.infodir =
|
||||||
opal_install_dirs_expand(opal_install_dirs.infodir);
|
opal_install_dirs_expand(opal_install_dirs.infodir);
|
||||||
opal_install_dirs.mandir =
|
expanded_dirs.mandir =
|
||||||
opal_install_dirs_expand(opal_install_dirs.mandir);
|
opal_install_dirs_expand(opal_install_dirs.mandir);
|
||||||
opal_install_dirs.pkgdatadir =
|
expanded_dirs.pkgdatadir =
|
||||||
opal_install_dirs_expand(opal_install_dirs.pkgdatadir);
|
opal_install_dirs_expand(opal_install_dirs.pkgdatadir);
|
||||||
opal_install_dirs.pkglibdir =
|
expanded_dirs.pkglibdir =
|
||||||
opal_install_dirs_expand(opal_install_dirs.pkglibdir);
|
opal_install_dirs_expand(opal_install_dirs.pkglibdir);
|
||||||
opal_install_dirs.pkgincludedir =
|
expanded_dirs.pkgincludedir =
|
||||||
opal_install_dirs_expand(opal_install_dirs.pkgincludedir);
|
opal_install_dirs_expand(opal_install_dirs.pkgincludedir);
|
||||||
|
opal_install_dirs = expanded_dirs;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
fprintf(stderr, "prefix: %s\n", opal_install_dirs.prefix);
|
fprintf(stderr, "prefix: %s\n", opal_install_dirs.prefix);
|
||||||
@ -179,7 +211,7 @@ opal_installdirs_base_close(void)
|
|||||||
free(opal_install_dirs.pkgincludedir);
|
free(opal_install_dirs.pkgincludedir);
|
||||||
|
|
||||||
for (item = opal_list_remove_first(&opal_installdirs_components);
|
for (item = opal_list_remove_first(&opal_installdirs_components);
|
||||||
NULL != item;
|
NULL != item;
|
||||||
item = opal_list_remove_first(&opal_installdirs_components)) {
|
item = opal_list_remove_first(&opal_installdirs_components)) {
|
||||||
OBJ_RELEASE(item);
|
OBJ_RELEASE(item);
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2007 Los Alamos National Security, LLC. All rights
|
* Copyright (c) 2006-2007 Los Alamos National Security, LLC. All rights
|
||||||
* reserved.
|
* reserved.
|
||||||
* Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
|
* Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
|
||||||
* Copyright (c) 2007 Sun Microsystem, Inc. All rights reserved.
|
* Copyright (c) 2007-2009 Sun Microsystem, Inc. All rights reserved.
|
||||||
* $COPYRIGHT$
|
* $COPYRIGHT$
|
||||||
*
|
*
|
||||||
* Additional copyrights may follow
|
* Additional copyrights may follow
|
||||||
*
|
*
|
||||||
* $HEADER$
|
* $HEADER$
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -19,77 +19,269 @@
|
|||||||
#include "opal/mca/installdirs/base/base.h"
|
#include "opal/mca/installdirs/base/base.h"
|
||||||
#include "opal/mca/installdirs/installdirs.h"
|
#include "opal/mca/installdirs/installdirs.h"
|
||||||
|
|
||||||
#define EXPAND_STRING(field) \
|
/*
|
||||||
do { \
|
* Read a field from an opal_install_dirs_t structure.
|
||||||
if (NULL != (start_pos = strstr(retval, "${" #field "}"))) { \
|
*
|
||||||
tmp = retval; \
|
* The field name is passed as a string + a length, and need not be
|
||||||
*start_pos = '\0'; \
|
* null terminated.
|
||||||
end_pos = start_pos + strlen("${" #field "}"); \
|
*
|
||||||
asprintf(&retval, "%s%s%s", tmp, \
|
* The implementation is reasonaly efficient, but perhaps less
|
||||||
opal_install_dirs.field + destdir_offset, \
|
* readable than a bunch of strncmp calls.
|
||||||
end_pos); \
|
*/
|
||||||
free(tmp); \
|
|
||||||
changed = true; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
#define CHKTRAIL(s,n) if (strncmp(field, #s, field_length - n) != 0) return NULL
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
field_lookup(const char *field,
|
||||||
|
int field_length,
|
||||||
|
opal_install_dirs_t *install_dirs)
|
||||||
|
{
|
||||||
|
switch (*field++) {
|
||||||
|
case 'b':
|
||||||
|
CHKTRAIL(indir, 1);
|
||||||
|
return install_dirs->bindir;
|
||||||
|
case 'd':
|
||||||
|
CHKTRAIL(atarootdir, 1);
|
||||||
|
return install_dirs->datarootdir;
|
||||||
|
case 'e':
|
||||||
|
CHKTRAIL(xec_prefix, 1);
|
||||||
|
return install_dirs->exec_prefix;
|
||||||
|
case 'i':
|
||||||
|
if ('n' != *field++) return NULL;
|
||||||
|
switch (*field++) {
|
||||||
|
case 'c':
|
||||||
|
CHKTRAIL(ludedir, 3);
|
||||||
|
return install_dirs->includedir;
|
||||||
|
case 'f':
|
||||||
|
CHKTRAIL(odir, 3);
|
||||||
|
return install_dirs->infodir;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
case 'l':
|
||||||
|
switch (*field++) {
|
||||||
|
case 'o':
|
||||||
|
CHKTRAIL(calstatedir, 2);
|
||||||
|
return install_dirs->localstatedir;
|
||||||
|
case 'i':
|
||||||
|
switch (*field++) {
|
||||||
|
case 'b':
|
||||||
|
switch (*field++) {
|
||||||
|
case 'd':
|
||||||
|
CHKTRAIL(ir, 4);
|
||||||
|
return install_dirs->libdir;
|
||||||
|
case 'e':
|
||||||
|
CHKTRAIL(xecdir, 4);
|
||||||
|
return install_dirs->libexecdir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
case 'm':
|
||||||
|
CHKTRAIL(andir, 1);
|
||||||
|
return install_dirs->mandir;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
switch (*field++) {
|
||||||
|
case 'r':
|
||||||
|
CHKTRAIL(efix, 2);
|
||||||
|
return install_dirs->prefix;
|
||||||
|
case 'k':
|
||||||
|
if ('g' == *field++) {
|
||||||
|
switch (*field++) {
|
||||||
|
case 'd':
|
||||||
|
CHKTRAIL(atadir, 4);
|
||||||
|
return install_dirs->pkgdatadir;
|
||||||
|
case 'l':
|
||||||
|
CHKTRAIL(ibdir, 4);
|
||||||
|
return install_dirs->pkglibdir;
|
||||||
|
case 'i':
|
||||||
|
CHKTRAIL(ncludedir, 4);
|
||||||
|
return install_dirs->pkgincludedir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
case 's':
|
||||||
|
switch (*field++) {
|
||||||
|
case 'b':
|
||||||
|
CHKTRAIL(indir, 2);
|
||||||
|
return install_dirs->sbindir;
|
||||||
|
case 'h':
|
||||||
|
CHKTRAIL(aredstatedir, 2);
|
||||||
|
return install_dirs->sharedstatedir;
|
||||||
|
case 'y':
|
||||||
|
CHKTRAIL(sconfdir, 2);
|
||||||
|
return install_dirs->sysconfdir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sets *output to the input string with any "${foo}" references expanded.
|
||||||
|
* The expansion values come from the fields of install_dirs.
|
||||||
|
*
|
||||||
|
* If dont_expand is non-NULL, references to the field it names are
|
||||||
|
* not expanded. (E.g., "${libdir}" will be copied as is to *output if
|
||||||
|
* dont_expand is "libdir".)
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
install_dirs_expand(const char *input,
|
||||||
|
char **output,
|
||||||
|
size_t *output_len,
|
||||||
|
size_t *j,
|
||||||
|
opal_install_dirs_t *install_dirs,
|
||||||
|
const char *dont_expand)
|
||||||
|
{
|
||||||
|
size_t len, i, m, n;
|
||||||
|
const char *expansion;
|
||||||
|
|
||||||
|
if (0 == *output_len) {
|
||||||
|
*output_len = 100;
|
||||||
|
*output = malloc(*output_len);
|
||||||
|
if (NULL == *output) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
len = strlen(input);
|
||||||
|
for (i = 0 ; i < len ; ++i) {
|
||||||
|
expansion = NULL;
|
||||||
|
if ('$' == input[i] && '{' == input[i+1]) {
|
||||||
|
for (n = 0; i + n + 2 < len; n++) {
|
||||||
|
if ('}' == input[i+n+2]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (NULL == dont_expand ||
|
||||||
|
strncmp(&input[i+2], dont_expand, n) != 0 ) {
|
||||||
|
expansion = field_lookup(&input[i+2], n, install_dirs);
|
||||||
|
} else {
|
||||||
|
expansion = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (NULL != expansion) {
|
||||||
|
install_dirs_expand(expansion, output, output_len, j, install_dirs,
|
||||||
|
dont_expand);
|
||||||
|
i += n + 2;
|
||||||
|
} else {
|
||||||
|
if (*j + 1 >= *output_len) {
|
||||||
|
*output_len += 100;
|
||||||
|
*output = realloc(*output, *output_len);
|
||||||
|
if (NULL == *output) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(*output)[(*j)++] = input[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(*output)[*j] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
opal_install_dirs_expand(const char* input)
|
opal_install_dirs_expand(const char* input)
|
||||||
{
|
{
|
||||||
size_t len, i;
|
|
||||||
bool needs_expand = false;
|
|
||||||
char *retval = NULL;
|
char *retval = NULL;
|
||||||
char *destdir = getenv("OPAL_DESTDIR");
|
char *destdir = getenv("OPAL_DESTDIR");
|
||||||
size_t destdir_offset = 0;
|
size_t j = 0, retval_len = 0;
|
||||||
|
|
||||||
if (NULL != destdir && strlen(destdir) > 0) {
|
if (NULL != destdir) {
|
||||||
destdir_offset = strlen(destdir);
|
j = strlen(destdir) + sizeof(OPAL_PATH_SEP) - 1;
|
||||||
|
retval_len = j + 100;
|
||||||
|
retval = malloc(retval_len);
|
||||||
|
if (NULL == retval) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
sprintf(retval, "%s%s", destdir, OPAL_PATH_SEP);
|
||||||
}
|
}
|
||||||
|
|
||||||
len = strlen(input);
|
install_dirs_expand(input, &retval, &retval_len, &j, &opal_install_dirs, NULL);
|
||||||
for (i = 0 ; i < len ; ++i) {
|
if (NULL != retval) {
|
||||||
if (input[i] == '$') {
|
retval = realloc(retval, j + 1);
|
||||||
needs_expand = true;
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
opal_install_dirs_infer(const char *inferred_field,
|
||||||
|
const char *infer_from_field,
|
||||||
|
size_t infer_from_field_len,
|
||||||
|
opal_install_dirs_t *component_installdirs)
|
||||||
|
{
|
||||||
|
const char *infer_from_path;
|
||||||
|
char *component_field = NULL;
|
||||||
|
size_t component_field_len = 0;
|
||||||
|
const char *installed_field = NULL;
|
||||||
|
char *p, *q;
|
||||||
|
size_t j = 0, inferred_field_len = strlen(inferred_field);
|
||||||
|
size_t leading, trailing, installed_field_len, retval_len;
|
||||||
|
char *retval;
|
||||||
|
|
||||||
|
infer_from_path = field_lookup(infer_from_field, infer_from_field_len,
|
||||||
|
component_installdirs);
|
||||||
|
install_dirs_expand(infer_from_path,
|
||||||
|
&component_field,
|
||||||
|
&component_field_len,
|
||||||
|
&j,
|
||||||
|
component_installdirs,
|
||||||
|
inferred_field);
|
||||||
|
|
||||||
|
installed_field = field_lookup(infer_from_field, infer_from_field_len,
|
||||||
|
&opal_install_dirs);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Let's say component_field is, "/path/${prefix}/bin", and
|
||||||
|
* infer_from_field is "bindir". Then we want to:
|
||||||
|
*
|
||||||
|
* 1. Make sure that opal_install_dirs.bindir starts with "/path/"
|
||||||
|
*
|
||||||
|
* 2. Make sure that opal_install_dirs.bindir ends with "/bin"
|
||||||
|
*
|
||||||
|
* 3. Return the string that appears between those
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (p = component_field; *p; p++) {
|
||||||
|
if (*p == '$' && p[1] == '{' &&
|
||||||
|
strncmp(p+2, inferred_field, inferred_field_len) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (*p == '\0') {
|
||||||
|
free(component_field);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
leading = p - component_field;
|
||||||
|
trailing = component_field + strlen(component_field) - p -
|
||||||
|
inferred_field_len - 3;
|
||||||
|
|
||||||
retval = strdup(input);
|
installed_field_len = strlen(installed_field);
|
||||||
if (NULL == retval) return NULL;
|
if (installed_field_len < trailing + leading) {
|
||||||
|
free(component_field);
|
||||||
if (needs_expand) {
|
return NULL;
|
||||||
bool changed = false;
|
|
||||||
char *start_pos, *end_pos, *tmp;
|
|
||||||
|
|
||||||
do {
|
|
||||||
changed = false;
|
|
||||||
EXPAND_STRING(prefix);
|
|
||||||
EXPAND_STRING(exec_prefix);
|
|
||||||
EXPAND_STRING(bindir);
|
|
||||||
EXPAND_STRING(sbindir);
|
|
||||||
EXPAND_STRING(libexecdir);
|
|
||||||
EXPAND_STRING(datarootdir);
|
|
||||||
EXPAND_STRING(datadir);
|
|
||||||
EXPAND_STRING(sysconfdir);
|
|
||||||
EXPAND_STRING(sharedstatedir);
|
|
||||||
EXPAND_STRING(localstatedir);
|
|
||||||
EXPAND_STRING(libdir);
|
|
||||||
EXPAND_STRING(includedir);
|
|
||||||
EXPAND_STRING(infodir);
|
|
||||||
EXPAND_STRING(mandir);
|
|
||||||
EXPAND_STRING(pkgdatadir);
|
|
||||||
EXPAND_STRING(pkglibdir);
|
|
||||||
EXPAND_STRING(pkgincludedir);
|
|
||||||
} while (changed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL != destdir) {
|
if (strncmp(component_field, installed_field, leading) != 0) {
|
||||||
char *tmp = retval;
|
free(component_field);
|
||||||
retval = opal_os_path(false, destdir, tmp, NULL);
|
return NULL;
|
||||||
free(tmp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strcmp(p + inferred_field_len + 3,
|
||||||
|
installed_field + installed_field_len - trailing) != 0) {
|
||||||
|
free(component_field);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(component_field);
|
||||||
|
retval_len = installed_field_len - leading - trailing;
|
||||||
|
retval = malloc(retval_len + 1);
|
||||||
|
if (NULL == retval) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memcpy(retval, installed_field + leading, retval_len);
|
||||||
|
retval[retval_len] = '\0';
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Загрузка…
Ссылка в новой задаче
Block a user