Skip to content

Commit

Permalink
added support for OpenBSD, fixes #13
Browse files Browse the repository at this point in the history
note that the returned executable path may be inaccurate as it relies on
exploring the PATH environment variable when argv[0] is not a relative or
absolute path
  • Loading branch information
gpakosz committed Sep 20, 2021
1 parent f0fb0a1 commit c47b123
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 8 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Supported platforms:
- NetBSD
- DragonFly BSD
- SunOS
- OpenBSD

Just drop `whereami.h` and `whereami.c` into your build and get started. (see
also [customizing compilation])
Expand Down
12 changes: 8 additions & 4 deletions _gnu-make/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,14 @@ ifeq ($(platform),)
override platform := freebsd
override architecture := $(__uname_m)
endif
ifeq ($(findstring cygwin,$(__uname_s)),cygwin)
override platform := cygwin
override architecture := $(__uname_m)
endif
ifeq ($(__uname_s),openbsd)
override platform := openbsd
override architecture := $(__uname_m)
endif
ifeq ($(findstring cygwin,$(__uname_s)),cygwin)
override platform := cygwin
override architecture := $(__uname_m)
endif
endif
ifeq ($(architecture),)
override architecture := unknown-architecture
Expand Down
117 changes: 113 additions & 4 deletions src/whereami.c
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
}

#elif defined(__DragonFly__) || defined(__FreeBSD__) || \
defined(__FreeBSD_kernel__) || defined(__NetBSD__)
defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)

#include <limits.h>
#include <stdlib.h>
Expand All @@ -581,6 +581,116 @@ int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
#include <sys/sysctl.h>
#include <dlfcn.h>

#if defined(__OpenBSD__)

#include <unistd.h>

WAI_FUNCSPEC
int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length)
{
char buffer1[4096];
char buffer2[PATH_MAX];
char buffer3[PATH_MAX];
char** argv = (char**)buffer1;
char* resolved = NULL;
int length = -1;

for (;;)
{
int mib[4] = { CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV };
size_t size;

if (sysctl(mib, 4, NULL, &size, NULL, 0) != 0)
break;

if (size > sizeof(buffer1))
{
argv = (char**)WAI_MALLOC(size);
if (!argv)
break;
}

if (sysctl(mib, 4, argv, &size, NULL, 0) != 0)
break;

if (strchr(argv[0], '/'))
{
resolved = realpath(argv[0], buffer2);
if (!resolved)
break;
}
else
{
const char* PATH = getenv("PATH");
if (!PATH)
break;

size_t argv0_length = strlen(argv[0]);

const char* begin = PATH;
while (1)
{
const char* separator = strchr(begin, ':');
const char* end = separator ? separator : begin + strlen(begin);

if (end - begin > 0)
{
if (*(end -1) == '/')
--end;

if (((end - begin) + 1 + argv0_length + 1) <= sizeof(buffer2))
{
memcpy(buffer2, begin, end - begin);
buffer2[end - begin] = '/';
memcpy(buffer2 + (end - begin) + 1, argv[0], argv0_length + 1);

resolved = realpath(buffer2, buffer3);
if (resolved)
break;
}
}

if (!separator)
break;

begin = ++separator;
}

if (!resolved)
break;
}

length = (int)strlen(resolved);
if (length <= capacity)
{
memcpy(out, resolved, length);

if (dirname_length)
{
int i;

for (i = length - 1; i >= 0; --i)
{
if (out[i] == '/')
{
*dirname_length = i;
break;
}
}
}
}

break;
}

if (argv != (char**)buffer1)
WAI_FREE(argv);

return length;
}

#else

WAI_FUNCSPEC
int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length)
{
Expand Down Expand Up @@ -629,12 +739,11 @@ int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length)
break;
}

if (path != buffer1)
WAI_FREE(path);

return length;
}

#endif

WAI_NOINLINE WAI_FUNCSPEC
int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
{
Expand Down

0 comments on commit c47b123

Please sign in to comment.