about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Kiddle <opk@zsh.org>2024-09-14 19:38:23 +0200
committerOliver Kiddle <opk@zsh.org>2024-09-14 19:38:23 +0200
commit701fad5021db0b3d07eaf90013a1ad760aaca78c (patch)
tree3c6a410d459b6c206b7e5811a0420fe24674c658
parent0cd2c953b486c85bc4b7983dee18065d0a53cb04 (diff)
downloadzsh-701fad5021db0b3d07eaf90013a1ad760aaca78c.tar.gz
zsh-701fad5021db0b3d07eaf90013a1ad760aaca78c.tar.xz
zsh-701fad5021db0b3d07eaf90013a1ad760aaca78c.zip
53085: support for BSDs in $ZSH_EXEPATH implementation
-rw-r--r--ChangeLog3
-rw-r--r--Src/init.c34
-rw-r--r--configure.ac2
3 files changed, 30 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index a4bec3999..2d06a3ffb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2024-09-14  Oliver Kiddle  <opk@zsh.org>
 
+	* 53085: configure.ac, Src/init.c: support for BSDs in
+	$ZSH_EXEPATH implementation
+
 	* 53084: configure.ac: yet another approach to the /dev/fd
 	autoconf test because of shells emulating /dev/fd
 
diff --git a/Src/init.c b/Src/init.c
index 70e878e20..2f914f96b 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -36,6 +36,10 @@
 
 #include "version.h"
 
+#ifdef HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
+
 /**/
 int noexitct = 0;
 
@@ -913,12 +917,6 @@ getmypath(const char *name, const char *cwd)
     char *buf;
     int namelen;
 
-    if (!name)
-	return NULL;
-    if (*name == '-')
-	++name;
-    if ((namelen = strlen(name)) == 0)
-	return NULL;
 #if defined(__APPLE__)
     {
 	uint32_t n = PATH_MAX;
@@ -934,6 +932,19 @@ getmypath(const char *name, const char *cwd)
 	else
 	    free(buf);
     }
+#elif defined(KERN_PROC_PATHNAME)
+    {
+#ifdef __NetBSD__
+	int mib[4] = { CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_PATHNAME };
+#else
+	int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
+#endif
+	size_t len = PATH_MAX;
+	buf = (char *) zalloc(PATH_MAX);
+	if (!sysctl(mib, 4, buf, &len, NULL, 0) && len > 1)
+	    return buf;
+	free(buf);
+    }
 #elif defined(PROC_SELF_EXE)
     {
 	ssize_t n;
@@ -947,6 +958,13 @@ getmypath(const char *name, const char *cwd)
 	    free(buf);
     }
 #endif
+
+    if (!name)
+	return NULL;
+    if (*name == '-')
+	++name;
+    if ((namelen = strlen(name)) == 0)
+	return NULL;
     /* guess the absolute pathname of 'name' */
     if (name[namelen-1] == '/')    /* name should not end with '/' */
 	return NULL;
@@ -964,7 +982,7 @@ getmypath(const char *name, const char *cwd)
     }
 #ifdef HAVE_REALPATH
     else {
-	/* search each dir in PARH */
+	/* search each dir in PATH */
 	const char *path, *sep;
 	char *real, *try;
 	int pathlen, dirlen;
@@ -978,7 +996,7 @@ getmypath(const char *name, const char *cwd)
 	do {
 	    sep = strchr(path, ':');
 	    dirlen = sep ? sep - path : strlen(path);
-	    strncpy(try, path, dirlen);
+	    memcpy(try, path, dirlen);
 	    try[dirlen] = '/';
 	    try[dirlen+1] = '\0';
 	    strcat(try, name);
diff --git a/configure.ac b/configure.ac
index e8f434274..2931f6615 100644
--- a/configure.ac
+++ b/configure.ac
@@ -636,7 +636,7 @@ fi
 AC_CHECK_HEADERS(sys/time.h sys/times.h sys/select.h termcap.h termio.h \
 		 termios.h sys/param.h sys/filio.h string.h memory.h \
 		 limits.h fcntl.h libc.h sys/utsname.h sys/resource.h \
-		 sys/random.h \
+		 sys/sysctl.h sys/random.h \
 		 locale.h errno.h stdio.h stdarg.h varargs.h stdlib.h \
 		 unistd.h sys/capability.h \
 		 utmp.h utmpx.h sys/types.h pwd.h grp.h poll.h sys/mman.h \