zsh-workers
 help / color / mirror / code / Atom feed
From: "Jun. T" <takimoto-j@kba.biglobe.ne.jp>
To: zsh-workers@zsh.org
Subject: Re: ksh compatibility: initial value of $_
Date: Sun, 9 Apr 2023 22:30:07 +0900	[thread overview]
Message-ID: <49E9BC96-C3F6-404B-8089-68FBD5960467@kba.biglobe.ne.jp> (raw)
In-Reply-To: <91076-1680970954.277199@scD9.nSRV.LVCF>


> 2023/04/09 1:22、Oliver Kiddle <opk@zsh.org>のメール:
> 
> dana wrote:
>> Maybe ZSH_EXECUTABLE? That kind of matches ZSH_SCRIPT too
> 
> That sounds good. Unless we want to take advantage of Bart's recent
> changes and put it in a namespace.

In the path below I used ZSH_EXEPATH to make it (somewhat) easier to
guess that it is a full pathname, but ZSH_EXECUTABLE (or any other
name) is OK for me.
If it will be put in a namespace, is it available only in the namespace,
or also in the toplevel namespace?


diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo
index 2db4210eb..08b3e79f6 100644
--- a/Doc/Zsh/params.yo
+++ b/Doc/Zsh/params.yo
@@ -1112,6 +1112,10 @@ item(tt(ZSH_EXECUTION_STRING))(
 If the shell was started with the option tt(-c), this contains
 the argument passed to the option.  Otherwise it is not set.
 )
+vindex(ZSH_EXEPATH)
+item(tt(ZSH_EXEPATH))(
+Full pathname of the executable file of current zsh process.
+)
 vindex(ZSH_NAME)
 item(tt(ZSH_NAME))(
 Expands to the basename of the command used to invoke this instance
diff --git a/Src/init.c b/Src/init.c
index 7e98af44c..f8acf2ff1 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -246,6 +246,9 @@ loop(int toplevel, int justonce)
 
 static int restricted;
 
+/* original argv[0] for initialization of $_. this is already metafied */
+static char *argv0;
+
 /**/
 static void
 parseargs(char *zsh_name, char **argv, char **runscript, char **cmdptr,
@@ -257,7 +260,7 @@ parseargs(char *zsh_name, char **argv, char **runscript, char **cmdptr,
     if (**argv == '-')
 	flags |= PARSEARGS_LOGIN;
 
-    argzero = posixzero = *argv++;
+    argv0 = argzero = posixzero = *argv++;
     SHIN = 0;
 
     /*
@@ -893,6 +896,106 @@ init_term(void)
     return 1;
 }
 
+/*
+ * Get (or guess) the absolute pathname of the current zsh exeutable.
+ * Try OS-specific method, and if it fails, guess the absolute pathname
+ * from argv0, pwd, and PATH. 'name' and 'cwd' are unmetefied versions of
+ * argv0 and pwd.
+ * Returns a zalloc()ed string (not metafied), or NULL if failed.
+ */
+#ifdef __APPLE__
+#include <mach-o/dyld.h>
+#endif
+
+/**/
+static char *
+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;
+	int ret;
+	buf = (char *)zalloc(PATH_MAX);
+	if ((ret = _NSGetExecutablePath(buf, &n)) < 0) {
+	    /* try again with increased buffer size */
+	    buf = (char *)zrealloc(buf, n);
+	    ret = _NSGetExecutablePath(buf, &n);
+	}
+	if (ret == 0 && strlen(buf) > 0)
+	    return buf;
+	else
+	    free(buf);
+    }
+#elif defined(PROC_SELF_EXE)
+    {
+	ssize_t n;
+	buf = (char *)zalloc(PATH_MAX);
+	n = readlink(PROC_SELF_EXE, buf, PATH_MAX);
+	if (n > 0 && n < PATH_MAX) {
+	    buf[n] = '\0';
+	    return buf;
+	}
+	else
+	    free(buf);
+    }
+#endif
+    /* guess the absolute pathname of 'name' */
+    if (name[namelen-1] == '/')    /* name should not end with '/' */
+	return NULL;
+    else if (name[0] == '/') {
+	/* name is already an absolute pathname */
+	return ztrdup(name);
+    }
+    else if (strchr(name, '/')) {
+	/* relative path */
+	if (!cwd)
+	    return NULL;
+	buf = (char *)zalloc(strlen(cwd) + namelen + 2);
+	sprintf(buf, "%s/%s", cwd, name);
+	return buf;
+    }
+#ifdef HAVE_REALPATH
+    else {
+	/* search each dir in PARH */
+	const char *path, *sep;
+	char *real, *try;
+	int pathlen, dirlen;
+
+	path = getenv("PATH");
+	if (!path || (pathlen = strlen(path)) == 0)
+	    return NULL;
+	/* for simplicity, allocate buf even if REALPATH_ACCEPTS_NULL is on */
+	buf = (char *)zalloc(PATH_MAX);
+	try = (char *)zalloc(pathlen + namelen + 2);
+	do {
+	    sep = strchr(path, ':');
+	    dirlen = sep ? sep - path : strlen(path);
+	    strncpy(try, path, dirlen);
+	    try[dirlen] = '/';
+	    try[dirlen+1] = '\0';
+	    strcat(try, name);
+	    real = realpath(try, buf);
+	    if (sep)
+		path = sep + 1;
+	} while (!real && sep);
+	free(try);
+	if (!real)
+	    free(buf);
+	return real;	/* this may be NULL */
+    }
+#endif
+    return NULL;
+}
+
 /* Initialize lots of global variables and hash tables */
 
 /**/
@@ -1195,6 +1298,18 @@ setupvals(char *cmd, char *runscript, char *zsh_name)
     /* Colour sequences for outputting colours in prompts and zle */
     set_default_colour_sequences();
 
+    /* ZSH_EXEPATH */
+    {
+	char *mypath, *exename, *cwd;
+	exename = unmetafy(ztrdup(argv0), NULL);
+	cwd = pwd ? unmetafy(ztrdup(pwd), NULL) : NULL;
+	mypath = getmypath(exename, cwd);
+	free(exename);
+	free(cwd);
+	if (mypath) {
+	    setsparam("ZSH_EXEPATH", metafy(mypath, -1, META_REALLOC));
+	}
+    }
     if (cmd)
 	setsparam("ZSH_EXECUTION_STRING", ztrdup(cmd));
     if (runscript)
diff --git a/configure.ac b/configure.ac
index e6ced85d9..d8a17791a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2011,6 +2011,25 @@ if test x$zsh_cv_sys_path_dev_fd != xno; then
   AC_DEFINE_UNQUOTED(PATH_DEV_FD, "$zsh_cv_sys_path_dev_fd")
 fi
 
+dnl ----------------------------------------------------
+dnl CHECK FOR SYMLINK TO THE CURRENT EXECUTABLE IN /proc
+dnl ----------------------------------------------------
+dnl Linux: /proc/self/exe
+dnl NetBSD: /proc/curproc/exe (or /proc/self/exe, but not /proc/curproc/file)
+dnl DragonFly: /proc/curproc/file
+dnl Solaris: /proc/self/path/a.out
+AH_TEMPLATE([PROC_SELF_EXE],
+[Define to the path of the symlink to the current executable file.])
+AC_CACHE_CHECK(for symlink to the current executable in /proc,
+zsh_cv_proc_self_exe,
+[for zsh_cv_proc_self_exe in /proc/self/exe /proc/curproc/exe \
+                             /proc/curproc/file /proc/self/path/a.out no; do
+   test -L $zsh_cv_proc_self_exe && break
+done])
+if test x$zsh_cv_proc_self_exe != xno; then
+  AC_DEFINE_UNQUOTED(PROC_SELF_EXE, "$zsh_cv_proc_self_exe")
+fi
+
 dnl ---------------------------------
 dnl CHECK FOR RFS SUPERROOT DIRECTORY
 dnl ---------------------------------





  reply	other threads:[~2023-04-09 13:30 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-28  1:52 Bart Schaefer
2023-03-23 10:40 ` Jun T
2023-03-31  8:18   ` Jun T
2023-03-31 14:31     ` Jun. T
2023-03-31 17:45       ` Bart Schaefer
2023-04-03 11:16         ` Jun. T
2023-04-03 16:48           ` Bart Schaefer
2023-03-31 19:02       ` Bart Schaefer
2023-03-31 19:03         ` Bart Schaefer
2023-04-03 12:13     ` Jun. T
2023-04-03 16:50       ` Bart Schaefer
2023-04-04 16:24         ` Jun. T
2023-04-05  1:03           ` Oliver Kiddle
2023-04-05  8:15             ` zeurkous
2023-04-05  9:00               ` Oliver Kiddle
2023-04-05 16:24             ` Jun. T
2023-04-05  8:14           ` dana
2023-04-05 18:16             ` Jun. T
2023-04-08  4:03               ` dana
2023-04-08 16:22                 ` Oliver Kiddle
2023-04-09 13:30                   ` Jun. T [this message]
2023-04-10  0:51                     ` Jun T
2023-04-15  5:02                   ` Felipe Contreras
2023-04-15 22:24               ` Bart Schaefer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=49E9BC96-C3F6-404B-8089-68FBD5960467@kba.biglobe.ne.jp \
    --to=takimoto-j@kba.biglobe.ne.jp \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).