Skip to content

Improve CommandLine.executablePath implementation on OpenBSD #1348

@grynspan

Description

@grynspan

Currently on OpenBSD, our implementation of CommandLine.executablePath just takes argv[0] verbatim. This works poorly if a relative path is used to start the process (e.g. ./foo). But we can improve it somewhat by calling realpath() as early as possible during execution. Something like:

#include <link.h>
#include <atomic>

static std::atomic<char *> executablePath = nullptr;

__attribute__((__constructor__(101)))
static void tryResolvingExecutablePath(void) {
  (void)dl_iterate_phdr([] (struct dl_phdr_info *info, size_t size, void *cookie) -> int {
    char *path = nullptr;

    if (info->dlpi_name) {
      if (strchr(info->dlpi_name, '/')) {
        path = realpath(info->dlpi_name, nullptr);
      }
      if (!path) {
        path = strdup(info->dlpi_name);
      }
      // NOTE: we do not attempt to resolve $PATH-relative paths here because we don't expect test executables to be installed into e.g. /usr/local/bin.
    }
    executablePath.store(path);

    return 1; // we only care about the first image
  }, nullptr);
}

extern "C" char *swt_getExecutablePath(void);
char *swt_getExecutablePath(void) {
  return executablePath.load();
}

We would need to use a constructor function to ensure this code runs as early as possible to minimize the risk of somebody changing the current working directory and breaking the relative path.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestexit-tests☠️ Work related to exit testsopenbsd🐡 OpenBSD support

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions