epicsGetExecName WIN32, Darwin, solaris, freebsd
This commit is contained in:
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
Reference in New Issue
Block a user