epicsGetExecName WIN32, Darwin, solaris, freebsd

This commit is contained in:
Michael Davidsaver
2018-04-26 14:33:58 -07:00
parent 32340584b4
commit 84831e13e7
7 changed files with 234 additions and 1 deletions
@@ -0,0 +1,50 @@
#include <string.h>
#include <stdlib.h>
#include <mach-o/dyld.h>
#define epicsExportSharedSymbols
#include <osiFileName.h>
char *epicsGetExecName(void)
{
uint32_t max = 64u;
char *ret = NULL;
while(1) {
char *temp = realloc(ret, max);
if(!temp) {
/* we treat alloc failure as terminal */
free(ret);
ret = NULL;
break;
}
ret = temp;
/* cf. "man 3 dyld" */
if(_NSGetExecutablePath(ret, &max)==0) {
/* max left unchanged */
ret[max-1] = '\0';
break;
}
/* max has been updated with required size */
}
/* TODO: _NSGetExecutablePath() doesn't follow symlinks */
return ret;
}
char *epicsGetExecDir(void)
{
char *ret = epicsGetExecName();
if(ret) {
char *sep = strrchr(ret, '/');
if(sep) {
/* nil the charactor after the / */
sep[1] = '\0';
}
}
return ret;
}
+5 -1
View File
@@ -24,7 +24,11 @@ char *epicsGetExecName(void)
ret = temp;
n = readlink("/proc/self/exe", ret, max);
if(n < max) {
if(n == -1) {
free(ret);
ret = NULL;
break;
} else if(n < max) {
/* readlink() never adds a nil */
ret[n] = '\0';
break;
@@ -0,0 +1,52 @@
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#define epicsExportSharedSymbols
#include <osiFileName.h>
char *epicsGetExecName(void)
{
size_t max = 128;
char *ret = NULL;
DWORD n;
while(1) {
char *temp = realloc(ret, max);
if(!temp) {
/* we treat alloc failure as terminal */
free(ret);
ret = NULL;
break;
}
ret = temp;
n = GetModuleFileName(NULL, ret, max);
if(n == 0) {
free(ret);
ret = NULL;
break;
} else if(n < max) {
ret[n] = '\0';
break;
}
max += 64;
}
return ret;
}
char *epicsGetExecDir(void)
{
char *ret = epicsGetExecName();
if(ret) {
char *sep = strrchr(ret, '\\');
if(sep) {
/* nil the charactor after the / */
sep[1] = '\0';
}
}
return ret;
}
@@ -0,0 +1,68 @@
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#define epicsExportSharedSymbols
#include <osiFileName.h>
char *epicsGetExecName(void)
{
size_t max = PATH_MAX;
char *ret = NULL;
ssize_t n;
while(1) {
char *temp = realloc(ret, max);
if(!temp) {
/* we treat alloc failure as terminal */
free(ret);
ret = NULL;
break;
}
ret = temp;
n = readlink("/proc/curproc/file", ret, max);
if(n == -1) {
free(ret);
ret = NULL;
break;
} else if(n < max) {
/* readlink() never adds a nil */
ret[n] = '\0';
break;
}
max += 64;
}
if(!ret) {
int mib[4];
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PATHNAME;
mib[3] = -1;
ret = malloc(max);
if(ret) {
sysctl(mib, 4, ret, &cb, NULL, 0);
/* TODO: error check */
}
}
return ret;
}
char *epicsGetExecDir(void)
{
char *ret = epicsGetExecName();
if(ret) {
char *sep = strrchr(ret, '/');
if(sep) {
/* nil the charactor after the / */
sep[1] = '\0';
}
}
return ret;
}
@@ -0,0 +1,30 @@
#include <string.h>
#include <stdlib.h>
#define epicsExportSharedSymbols
#include <osiFileName.h>
char *epicsGetExecName(void)
{
const char *raw = getexecname();
char *ret = NULL;
/* manpage says getexecname() might return a relative path. we treat this as an error */
if(raw[0]=='/') {
ret = strdup(raw);
}
return ret;
}
char *epicsGetExecDir(void)
{
char *ret = epicsGetExecName();
if(ret) {
char *sep = strrchr(ret, '/');
if(sep) {
/* nil the charactor after the / */
sep[1] = '\0';
}
}
return ret;
}
+5
View File
@@ -232,6 +232,11 @@ osiSockTest_SRCS += osiSockTest.c
testHarness_SRCS += osiSockTest.c
TESTS += osiSockTest
TESTPROD_HOST += testexecname
testexecname_SRCS += testexecname.c
# no point in including in testHarness. Not implemented for RTEMS/vxWorks.
TESTS += testexecname
ifeq ($(BUILD_CLASS),HOST)
ifneq ($(OS_CLASS),WIN32)
# This test can only be run on a build host, and is broken on Windows
+24
View File
@@ -0,0 +1,24 @@
#include <string.h>
#include <epicsUnitTest.h>
#include <testMain.h>
#include <osiFileName.h>
MAIN(testexecname)
{
testPlan(1);
{
char *buf = epicsGetExecName();
if(!buf) {
testSkip(1, "epicsGetExecName() not available for this target");
} else {
char *loc = strstr(buf, "testexecname");
testOk(!!loc, "Find \"testexecname\" in \"%s\"", buf);
}
}
return testDone();
}