aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2025-04-02 06:02:35 +0000
committerLaurent Bercot <ska@appnovation.com>2025-04-02 06:02:35 +0000
commit200a70765a503fc94b546e5a52fdd90a59eee3b3 (patch)
tree343e317b83e45454239cdb50a50b3649bcdc174f
parent56ab53289c60c6fbb06f8d548d353535d5ed1140 (diff)
downloadskalibs-200a70765a503fc94b546e5a52fdd90a59eee3b3.tar.gz
Add sagetexecname() and all the necessary infrastructure
Signed-off-by: Laurent Bercot <ska@appnovation.com>
-rw-r--r--NEWS3
-rwxr-xr-xconfigure32
-rw-r--r--doc/libstddjb/djbunix.html6
-rw-r--r--doc/upgrade.html1
-rw-r--r--package/deps.mak1
-rw-r--r--src/include/skalibs/djbunix.h1
-rw-r--r--src/libstddjb/sagetexecname.c111
-rw-r--r--src/sysdeps/try_nsgetexecutablepath.c14
-rw-r--r--src/sysdeps/trygetauxval.c12
-rw-r--r--src/sysdeps/trygetexecname.c11
-rw-r--r--src/sysdeps/trykernprocpathname.c18
-rw-r--r--src/sysdeps/tryprocselfexe.c13
-rwxr-xr-xtools/gen-sysdepsh.sh12
13 files changed, 231 insertions, 4 deletions
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 *<em>sa</em>.
Returns 0 if it succeeds and -1 (and sets errno) if it fails.
</p>
+<p>
+<code> int sagetexecname (stralloc *sa) </code> <br />
+Appends the full path of the current executable to *<em>sa</em>.
+Returns 0 if it succeeds and -1 (and sets errno) if it fails.
+</p>
+
<h3> Temporization </h3>
<p>
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 @@
<li> New <tt>buffer_timed_getv</tt>, <tt>buffer_timed_putv</tt>,
<tt>timed_read</tt> and <tt>timed_readv</tt>,
<tt>timed_write</tt> and <tt>timed_writev</tt> functions. </li>
+ <li> New sysdeps, and new <tt>sagetexecname</tt> function. </li>
</ul>
<h2> in 2.14.3.0 </h2>
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 <skalibs/sysdeps.h>
+
+#if defined(SKALIBS_PROCSELFEXE)
+
+#include <skalibs/stralloc.h>
+#include <skalibs/djbunix.h>
+
+int sagetexecname (stralloc *sa)
+{
+ return sareadlink(sa, SKALIBS_PROCSELFEXE) ;
+}
+
+#elif defined(SKALIBS_HASGETEXECNAME)
+
+#include <skalibs/nonposix.h>
+#include <stdlib.h>
+
+#include <skalibs/stralloc.h>
+#include <skalibs/djbunix.h>
+
+int sagetexecname (stralloc *sa)
+{
+ return sarealpath(sa, getexecname()) ;
+}
+
+#elif defined(SKALIBS_HASKERNPROCPATHNAME)
+
+#include <skalibs/nonposix.h>
+#ifdef __NetBSD__
+#include <sys/param.h>
+#endif
+#include <limits.h>
+#include <sys/sysctl.h>
+
+#include <skalibs/stralloc.h>
+#include <skalibs/djbunix.h>
+
+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 <skalibs/nonposix.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include <macho-o/dyld.h>
+
+#include <skalibs/stralloc.h>
+#include <skalibs/djbunix.h>
+
+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 <skalibs/nonposix.h>
+#include <sys/auxv.h>
+
+#include <skalibs/stralloc.h>
+#include <skalibs/djbunix.h>
+
+int sagetexecname (stralloc *sa)
+{
+ unsigned long x = getauxval(AT_EXECFN) ;
+ return sarealpath(sa, (char const *)x) ;
+}
+
+#elif defined(SKALIBS_HASDLADDR)
+
+#include <skalibs/nonposix.h>
+#include <dlfcn.h>
+
+#include <skalibs/stralloc.h>
+#include <skalibs/djbunix.h>
+
+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 <errno.h>
+
+#include <skalibs/stralloc.h>
+#include <skalibs/djbunix.h>
+
+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 <stdint.h>
+#include <mach-o/dyld.h>
+
+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 <sys/auxv.h>
+
+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 <stdlib.h>
+
+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 <sys/types.h>
+#ifdef __NetBSD__
+#include <sys/param.h>
+#endif
+#include <sys/sysctl.h>
+
+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 <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+
+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