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
---
NEWS | 3 +
configure | 32 ++++++++++
doc/libstddjb/djbunix.html | 6 ++
doc/upgrade.html | 1 +
package/deps.mak | 1 +
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 ++++
tools/gen-sysdepsh.sh | 12 ++--
13 files changed, 231 insertions(+), 4 deletions(-)
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
diff --git a/NEWS b/NEWS
index 06bc7f8..20fdf45 100644
--- a/NEWS
+++ b/NEWS
@@ -3,9 +3,12 @@ Changelog for skalibs.
In 2.14.4.0
-----------
+ - Bugfixes.
- Documentation fixes. (This file, in particular.)
- New functions: buffer_timed_getv, buffer_timed_putv,
timed_read, timed_readv, timed_Write, timed_writev
+ - New sysdeps, better handling of variable sysdeps
+ - New function: sagetexecname
In 2.14.3.0
diff --git a/configure b/configure
index e971be8..e96329f 100755
--- a/configure
+++ b/configure
@@ -51,6 +51,7 @@ Sysdeps autodetection override:
List of mandatory sysdeps to provide by hand for cross-compiling:
devurandom (yes|no): =yes if you have a working /dev/urandom
posixspawnearlyreturn (yes|no): =yes if you have an old glibc or otherwise bad posix_spawn
+ procselfexe (yes|no): =yes if you have a working /proc/self/exe virtual symlink
EOF
exit 0
}
@@ -187,6 +188,32 @@ choose () {
fi
}
+choosevalue () {
+ name="$1"
+ if iscached "$name" ; then return ; fi
+ if test -n "$cross" ; then
+ rm -f try$name
+ fail "$0: sysdep $name cannot be autodetected when cross-compiling. Please manually provide a value with the --with-sysdep-${name}=value... option."
+ fi
+ echo "Finding a suitable value for $2..."
+ shift 2
+ r=none
+ if $CC_AUTO $CPPFLAGS_AUTO $CPPFLAGS $CPPFLAGS_POST $CFLAGS_AUTO $CFLAGS $CFLAGS_POST -o "$tmpo" -c src/sysdeps/try$name.c 2>/dev/null \
+ && $CC_AUTO $CFLAGS_AUTO $CFLAGS $CFLAGS_POST $LDFLAGS_AUTO $LDFLAGS $LDFLAGS_POST -o try$name "$tmpo" 2>/dev/null ; then
+ while test -n "$1" ; do
+ ./try$name "$1" >/dev/null 2>&1
+ case "$?" in
+ 111) fail "$0: test crashed, aborting." ;;
+ 0) r="$1" ; break ;;
+ esac
+ shift
+ done
+ fi
+ rm -f try$name
+ echo "$name: $r" >> $sysdeps/sysdeps
+ echo " ... $r"
+}
+
trybasic () {
$CC_AUTO $CPPFLAGS_AUTO $CPPFLAGS $CPPFLAGS_POST $CFLAGS_AUTO $CFLAGS $CFLAGS_POST -o "$tmpo" -c "$1" 2>/dev/null
}
@@ -662,10 +689,15 @@ choose cl posixspawnsetsid 'POSIX_SPAWN_SETSID' $spawn_lib
choose cl posixspawnsetsidnp 'POSIX_SPAWN_SETSID_NP' $spawn_lib
choose cl posixspawnchdir 'posix_spawn_file_actions_addchdir()' $spawn_lib
choose cl posixspawnchdirnp 'posix_spawn_file_actions_addchdir_np()' $spawn_lib
+choose cl getauxval 'getauxval()'
+choose cl kernprocpathname 'the KERN_PROC_PATHNAME sysctl'
+choose cl _nsgetexecutablepath '_NSGetExecutablePath()'
+choose cl getexecname 'getexecname()'
# Here are the evil irreducible run-time sysdeps.
choose clr devurandom '/dev/urandom'
choose clr posixspawnearlyreturn 'posix_spawn() return early' $spawn_lib
+choosevalue procselfexe '/proc/self/exe' /proc/self/exe /proc/curproc/exe /proc/curproc/file /proc/self/path/a.out
# Finally, produce config.mak and config.h
diff --git a/doc/libstddjb/djbunix.html b/doc/libstddjb/djbunix.html
index 39b100c..63eca54 100644
--- a/doc/libstddjb/djbunix.html
+++ b/doc/libstddjb/djbunix.html
@@ -690,6 +690,12 @@ Appends the machine's hostname to *sa.
Returns 0 if it succeeds and -1 (and sets errno) if it fails.
+
+ int sagetexecname (stralloc *sa)
+Appends the full path of the current executable to *sa.
+Returns 0 if it succeeds and -1 (and sets errno) if it fails.
+
+
Temporization
diff --git a/doc/upgrade.html b/doc/upgrade.html
index 147eafa..cb8aa00 100644
--- a/doc/upgrade.html
+++ b/doc/upgrade.html
@@ -22,6 +22,7 @@
New buffer_timed_getv, buffer_timed_putv,
timed_read and timed_readv,
timed_write and timed_writev functions.
+ New sysdeps, and new sagetexecname function.
in 2.14.3.0
diff --git a/package/deps.mak b/package/deps.mak
index a69e12d..abd27b5 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -487,6 +487,7 @@ src/libstddjb/rmstar.o src/libstddjb/rmstar.lo: src/libstddjb/rmstar.c src/inclu
src/libstddjb/sabasename.o src/libstddjb/sabasename.lo: src/libstddjb/sabasename.c src/include/skalibs/bytestr.h src/include/skalibs/djbunix.h src/include/skalibs/stralloc.h
src/libstddjb/sadirname.o src/libstddjb/sadirname.lo: src/libstddjb/sadirname.c src/include/skalibs/bytestr.h src/include/skalibs/djbunix.h src/include/skalibs/stralloc.h
src/libstddjb/sagetcwd.o src/libstddjb/sagetcwd.lo: src/libstddjb/sagetcwd.c src/include/skalibs/djbunix.h src/include/skalibs/stralloc.h
+src/libstddjb/sagetexecname.o src/libstddjb/sagetexecname.lo: src/libstddjb/sagetexecname.c src/include/skalibs/djbunix.h src/include/skalibs/nonposix.h src/include/skalibs/stralloc.h src/include/skalibs/sysdeps.h
src/libstddjb/sagethostname.o src/libstddjb/sagethostname.lo: src/libstddjb/sagethostname.c src/include/skalibs/djbunix.h src/include/skalibs/stralloc.h
src/libstddjb/sals.o src/libstddjb/sals.lo: src/libstddjb/sals.c src/include/skalibs/direntry.h src/include/skalibs/djbunix.h src/include/skalibs/stralloc.h
src/libstddjb/sanitize_read.o src/libstddjb/sanitize_read.lo: src/libstddjb/sanitize_read.c src/include/skalibs/allreadwrite.h src/include/skalibs/error.h
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 ;
+}
diff --git a/tools/gen-sysdepsh.sh b/tools/gen-sysdepsh.sh
index c699feb..4cb5f3d 100755
--- a/tools/gen-sysdepsh.sh
+++ b/tools/gen-sysdepsh.sh
@@ -24,13 +24,17 @@ while read k v ; do
elif test ${k} != ${k##SIZEOF} ; then
echo "#undef SKALIBS_$k"
echo "#define SKALIBS_$k $v"
- elif test ${k} = ENDIANNESS ; then
- echo '#undef SKALIBS_ENDIANNESS'
- echo "#define SKALIBS_ENDIANNESS \"$v\""
else
- echo "#undef SKALIBS_HAS$k"
if test $v = yes ; then
+ echo "#undef SKALIBS_HAS$k"
echo "#define SKALIBS_HAS$k"
+ elif test $v = no ; then
+ echo "#undef SKALIBS_HAS$k"
+ else
+ echo "#undef SKALIBS_$k"
+ if test $v != none ; then
+ echo "#define SKALIBS_$k \"$v\""
+ fi
fi
fi
echo
--
cgit v1.3.1