예제 #1
0
파일: pnmpize.c 프로젝트: RWTH-ELP/PnMPI
int main(int argc, char **argv)
{
  /* Parse our arguments: Options will be parsed until the first non-option is
   * found. Parsed arguments will manipulate the current environment to initial-
   * ize it for use with P^nMPI. If there are no additional non-options in our
   * arguments, argp_parse will print the usage message and exit immediatly, no
   * extra evaluation is required here. The index of the first non-option will
   * be stored in ind. */
  int ind;
  argp_parse(&argp, argc, argv, ARGP_IN_ORDER, &ind, NULL);

#ifdef __APPLE__
  /* For apple systems, add libpnmpif to DYLD_INSERT_LIBRARIES, the apple ver-
   * sion of LD_PRELOAD. DYLD_FORCE_FLAT_NAMESPACE has to be set, to get all
   * symbols in the same namespace. Otherwise P^nMPI and libmpi won't see each
   * other and no preloading will happen. */
  appendenv("DYLD_INSERT_LIBRARIES",
            PNMPI_LIBRARY_DIR "/" PNMPI_LIBRARY_NAME ".dylib");
  setenv("DYLD_FORCE_FLAT_NAMESPACE", "1", 1);

#else
  /* For other systems (Linux and other UNIX platforms), add libpnmpif to
   * LD_PRELOAD to load P^nMPI in front of libmpi. */
  appendenv("LD_PRELOAD", PNMPI_LIBRARY_DIR "/" PNMPI_LIBRARY_NAME ".so");
#endif

  /* Execute the utility. If the utility could be started, pnmpize will exit
   * here. In any other case, the following error processing will be called. */
  if (execvp(argv[ind], argv + ind) < 0)
    {
      fprintf(stderr, "Could not execute %s: %s\n", argv[ind], strerror(errno));
      return EXIT_FAILURE;
    }
}
예제 #2
0
파일: pnmpize.c 프로젝트: LLNL/PnMPI
/** \brief Argument parser for argp.
 *
 * \note See argp parser documentation for detailed information about the
 *  structure and functionality of function.
 */
static error_t parse_arguments(int key, char *arg, struct argp_state *state)
{
  switch (key)
    {
    case 'c': setenv("PNMPI_CONF", arg, 1); break;
    case 'd': set_dbglevel(state, arg); break;
    case 'm': appendenv("PNMPI_LIB_PATH", arg, 1); break;
    case 'n': setenv("PNMPI_DBGNODE", arg, 1); break;
    case 'q':
    case 's':
      setenv("PNMPI_BE_SILENT", "1", 1);
      break;

#ifdef ENABLE_FORTRAN
    case 'f':
        preload_library(PNMPI_FORTRAN_LIBRARY_NAME);
        pnmpi_library_loaded = 1;
        break;
#endif

    /* If we have parsed all options, iterate through all non-options in argv.
     * If at there are no non-options in our arguments (argv), the user
     * specified no utility to call, so we'll print the argp usage here, which
     * will exit pnmpize immediately after printing the usage message. */
    case ARGP_KEY_END:
      if (state->arg_num == 0)
        argp_usage(state);
      break;

    default: return ARGP_ERR_UNKNOWN;
    }

  return 0;
}
예제 #3
0
파일: pnmpize.c 프로젝트: LLNL/PnMPI
/**
 * Preload a specific library.
 *
 *
 * @param library The library to be preloaded.
 */
static void preload_library(const char *library)
{
#ifdef __APPLE__
  /* For apple systems, add the library to DYLD_INSERT_LIBRARIES, the macOS
   * version of LD_PRELOAD. DYLD_FORCE_FLAT_NAMESPACE has to be set, to get all
   * symbols in the same namespace. Otherwise P^nMPI and libmpi won't see each
   * other and no preloading will happen. */
  char *lib = find_library(library);
  appendenv("DYLD_INSERT_LIBRARIES", lib, 0);
  setenv("DYLD_FORCE_FLAT_NAMESPACE", "1", 1);
  free(lib);

#else
  /* For other systems (Linux and other UNIX platforms), add the library to
   * LD_PRELOAD to load P^nMPI in front of libmpi. No path to the shared object,
   * but just the filename is required, as the dynamic loader searches in the
   * LD_LIBRARY_PATH for this file. */
  appendenv("LD_LIBRARY_PATH", PNMPI_LIBRARY_PATH, 0);
  appendenv("LD_PRELOAD", library, 0);
#endif
}
예제 #4
0
파일: pnmpize.c 프로젝트: LLNL/PnMPI
/** \brief Search for a library in the search paths of the dynamic linker.
 *
 * \details This function searches for \p library in the search path of the
 *  dynamic linker. Its use is to get the same behavior as for `LD_PRELOAD`,
 *  that the library doesn't have to be at a fixed place.
 *
 *
 * \param library The library to be searched.
 *
 * \return If the library has been found, a pointer to a new allocated string
 *  containing its path will be returned. Remember to free this buffer!
 * \return If the library could not be found in any path, the application will
 *  be exited immediately with an error code.
 */
static char *find_library(const char *library)
{
  /* As the DYLD_LIBRARY_PATH variable might not reach PnMPIze because of the
   * security features of mac OS, we'll set this variable with the contents of
   * PNMPI_PATH, if it doesn't exist yet. */
  if (getenv("DYLD_LIBRARY_PATH") == NULL)
    {
      const char *tmp = getenv("PNMPI_PATH");
      if (tmp != NULL)
        setenv("DYLD_LIBRARY_PATH", tmp, 0);
    }

  /* Generate the library search path, combined on first DYLD_LIBRARY_PATH and
   * then DYLD_FALLBACK_LIBRARY_PATH. If the latter is not defined in the
   * environment, it will be set by the default value of the mac OS dynamic
   * linker. */
  if (!getenv("DYLD_FALLBACK_LIBRARY_PATH"))
    {
      const char *home = getenv("HOME");
      size_t len = strlen(home) + 5 + sizeof(DEFAULT_FALLBACK_LIBRARY_PATH);
      char buffer[len];
      snprintf(buffer, len, "%s/lib:%s", home, DEFAULT_FALLBACK_LIBRARY_PATH);
      setenv("DYLD_FALLBACK_LIBRARY_PATH", buffer, 0);
    }
  appendenv("DYLD_LIBRARY_PATH", getenv("DYLD_FALLBACK_LIBRARY_PATH"), 0);

  /* DYLD_LIBRARY_PATH is a colon separated list of paths to search for
   * libraries. Iterate over all of these paths now to find the searched one. */
  char *path = strtok(getenv("DYLD_LIBRARY_PATH"), ":");
  while (path)
    {
      /* Check if the searched library can be found in this path. If yes,
       * duplicate the buffer and return this string, so the callee can use this
       * path. */
      size_t len = strlen(path) + strlen(library) + 2;
      char buffer[len];
      snprintf(buffer, len, "%s/%s", path, library);
      if (access(buffer, F_OK) != -1)
        return strdup(buffer);

      /* Get the next path. */
      path = strtok(NULL, ":");
    }

  /* The searched library can't be found in any path. */
  fprintf(stderr, "Could not find the PnMPI library.\n");
  exit(EXIT_FAILURE);
}