From 200a70765a503fc94b546e5a52fdd90a59eee3b3 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Wed, 2 Apr 2025 06:02:35 +0000 Subject: Add sagetexecname() and all the necessary infrastructure Signed-off-by: Laurent Bercot --- src/include/skalibs/djbunix.h | 1 + src/libstddjb/sagetexecname.c | 111 ++++++++++++++++++++++++++++++++++ src/sysdeps/try_nsgetexecutablepath.c | 14 +++++ src/sysdeps/trygetauxval.c | 12 ++++ src/sysdeps/trygetexecname.c | 11 ++++ src/sysdeps/trykernprocpathname.c | 18 ++++++ src/sysdeps/tryprocselfexe.c | 13 ++++ 7 files changed, 180 insertions(+) create mode 100644 src/libstddjb/sagetexecname.c create mode 100644 src/sysdeps/try_nsgetexecutablepath.c create mode 100644 src/sysdeps/trygetauxval.c create mode 100644 src/sysdeps/trygetexecname.c create mode 100644 src/sysdeps/trykernprocpathname.c create mode 100644 src/sysdeps/tryprocselfexe.c (limited to 'src') diff --git a/src/include/skalibs/djbunix.h b/src/include/skalibs/djbunix.h index 5bef6ec..0304ce8 100644 --- a/src/include/skalibs/djbunix.h +++ b/src/include/skalibs/djbunix.h @@ -82,6 +82,7 @@ extern int sadirname (stralloc *, char const *, size_t) ; extern int sagetcwd (stralloc *) ; extern int sareadlink (stralloc *, char const *) ; extern int sagethostname (stralloc *) ; +extern int sagetexecname (stralloc *) ; #define slurp(sa, fd) slurpn((fd), (sa), 0) #define openslurpclose(sa, fn) openslurpnclose((fn), (sa), 0) diff --git a/src/libstddjb/sagetexecname.c b/src/libstddjb/sagetexecname.c new file mode 100644 index 0000000..d3c300b --- /dev/null +++ b/src/libstddjb/sagetexecname.c @@ -0,0 +1,111 @@ +/* ISC license. */ + +#include + +#if defined(SKALIBS_PROCSELFEXE) + +#include +#include + +int sagetexecname (stralloc *sa) +{ + return sareadlink(sa, SKALIBS_PROCSELFEXE) ; +} + +#elif defined(SKALIBS_HASGETEXECNAME) + +#include +#include + +#include +#include + +int sagetexecname (stralloc *sa) +{ + return sarealpath(sa, getexecname()) ; +} + +#elif defined(SKALIBS_HASKERNPROCPATHNAME) + +#include +#ifdef __NetBSD__ +#include +#endif +#include +#include + +#include +#include + +int sagetexecname (stralloc *sa) +{ + int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 } ; + char buf[PATH_MAX] ; + size_t len = sizeof(buf) ; + if (sysctl(mib, 4, buf, &len, 0, 0) == -1) return -1 ; + if (!stralloc_catb(sa, buf, len) || !stralloc_0(sa)) return -1 ; + return 0 ; +} + +#elif defined(SKALIBS_HAS_NSGETEXECUTABLEPATH) + +#include +#include +#include +#include + +#include +#include + +int sagetexecname (stralloc *sa) +{ + char buf[4096] ; + uint32_t len = sizeof(buf) ; + if (_NSGetExecutablePath(buf, &len) == -1) return -1 ; + return sarealpath(sa, buf) ; +} + +#elif defined(SKALIBS_HASGETAUXVAL) + +#include +#include + +#include +#include + +int sagetexecname (stralloc *sa) +{ + unsigned long x = getauxval(AT_EXECFN) ; + return sarealpath(sa, (char const *)x) ; +} + +#elif defined(SKALIBS_HASDLADDR) + +#include +#include + +#include +#include + +int sagetexecname (stralloc *sa) +{ + Dl_info info ; + if (!dladdr(&main, &info)) return -1 ; + if (!stralloc_cats(sa, info.dli_fname) || !stralloc_0(sa)) return -1 ; + return 0 ; +} + +#else /* we tried */ + +#include + +#include +#include + +int sagetexecname (stralloc *sa) +{ + errno = ENOSYS ; + return -1 ; +} + +#endif diff --git a/src/sysdeps/try_nsgetexecutablepath.c b/src/sysdeps/try_nsgetexecutablepath.c new file mode 100644 index 0000000..e2599cc --- /dev/null +++ b/src/sysdeps/try_nsgetexecutablepath.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#include +#include + +int main (void) +{ + char buf[1024] ; + uint32_t len = sizeof(buf) ; + return _NSGetExecutablePath(buf, &len) >= 0 ; +} diff --git a/src/sysdeps/trygetauxval.c b/src/sysdeps/trygetauxval.c new file mode 100644 index 0000000..cbf3da4 --- /dev/null +++ b/src/sysdeps/trygetauxval.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#include + +int main (void) +{ + unsigned long x = getauxval(AT_EXECFN) ; + return 0 ; +} diff --git a/src/sysdeps/trygetexecname.c b/src/sysdeps/trygetexecname.c new file mode 100644 index 0000000..ac65071 --- /dev/null +++ b/src/sysdeps/trygetexecname.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#include + +int main (void) +{ + return !!getexecname() ; +} diff --git a/src/sysdeps/trykernprocpathname.c b/src/sysdeps/trykernprocpathname.c new file mode 100644 index 0000000..b8e2867 --- /dev/null +++ b/src/sysdeps/trykernprocpathname.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#include +#ifdef __NetBSD__ +#include +#endif +#include + +int main (void) +{ + int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 } ; + char buf[1024] ; + size_t len = sizeof(buf) ; + return sysctl(mib, 4, buf, &len, 0, 0) >= 0 ; +} diff --git a/src/sysdeps/tryprocselfexe.c b/src/sysdeps/tryprocselfexe.c new file mode 100644 index 0000000..e8b8a88 --- /dev/null +++ b/src/sysdeps/tryprocselfexe.c @@ -0,0 +1,13 @@ +/* ISC license */ + +#include +#include +#include + +int main (int argc, char const *const *argv) +{ + char buf[8192] ; + if (argc < 2) return 111 ; + ssize_t r = readlink(argv[1], buf, 8192) ; + return r == -1 ? errno == EIO || errno == ELOOP ? 111 : 1 : r <= 1 ; +} -- cgit v1.3.1