mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-06-27 00:11:00 +02:00
51639: new parameter ZSH_EXEPATH (full path of zsh executable)
The full pathname is obatined by a reliable method on macOS and systems that support procfs. But on other systems (FreeBSD, OpenBSD, ...) it is guessed from argv[0], PWD and PATH.
This commit is contained in:
parent
8a9aea907a
commit
e5f8cc99f5
4 changed files with 145 additions and 1 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2023-04-11 Jun-ichi Takimoto <takimoto-j@kba.biglobe.ne.jp>
|
||||||
|
|
||||||
|
* 51639: Doc/Zsh/params.yo, Src/init.c, configure.ac: add new
|
||||||
|
parameter ZSH_EXEPATH that is set to the full pathname of the
|
||||||
|
executable file of the current zsh
|
||||||
|
|
||||||
2023-04-09 Jun-ichi Takimoto <takimoto-j@kba.biglobe.ne.jp>
|
2023-04-09 Jun-ichi Takimoto <takimoto-j@kba.biglobe.ne.jp>
|
||||||
|
|
||||||
* 51631: Doc/Zsh/params.yo, Src/init.c: initialize $_ by copying
|
* 51631: Doc/Zsh/params.yo, Src/init.c: initialize $_ by copying
|
||||||
|
|
|
@ -1112,6 +1112,10 @@ item(tt(ZSH_EXECUTION_STRING))(
|
||||||
If the shell was started with the option tt(-c), this contains
|
If the shell was started with the option tt(-c), this contains
|
||||||
the argument passed to the option. Otherwise it is not set.
|
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 the current zsh process.
|
||||||
|
)
|
||||||
vindex(ZSH_NAME)
|
vindex(ZSH_NAME)
|
||||||
item(tt(ZSH_NAME))(
|
item(tt(ZSH_NAME))(
|
||||||
Expands to the basename of the command used to invoke this instance
|
Expands to the basename of the command used to invoke this instance
|
||||||
|
|
117
Src/init.c
117
Src/init.c
|
@ -246,6 +246,9 @@ loop(int toplevel, int justonce)
|
||||||
|
|
||||||
static int restricted;
|
static int restricted;
|
||||||
|
|
||||||
|
/* original argv[0]. This is already metafied */
|
||||||
|
static char *argv0;
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static void
|
static void
|
||||||
parseargs(char *zsh_name, char **argv, char **runscript, char **cmdptr,
|
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 == '-')
|
if (**argv == '-')
|
||||||
flags |= PARSEARGS_LOGIN;
|
flags |= PARSEARGS_LOGIN;
|
||||||
|
|
||||||
argzero = posixzero = *argv++;
|
argv0 = argzero = posixzero = *argv++;
|
||||||
SHIN = 0;
|
SHIN = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -893,6 +896,106 @@ init_term(void)
|
||||||
return 1;
|
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 */
|
/* 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 */
|
/* Colour sequences for outputting colours in prompts and zle */
|
||||||
set_default_colour_sequences();
|
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)
|
if (cmd)
|
||||||
setsparam("ZSH_EXECUTION_STRING", ztrdup(cmd));
|
setsparam("ZSH_EXECUTION_STRING", ztrdup(cmd));
|
||||||
if (runscript)
|
if (runscript)
|
||||||
|
|
19
configure.ac
19
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")
|
AC_DEFINE_UNQUOTED(PATH_DEV_FD, "$zsh_cv_sys_path_dev_fd")
|
||||||
fi
|
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 ---------------------------------
|
||||||
dnl CHECK FOR RFS SUPERROOT DIRECTORY
|
dnl CHECK FOR RFS SUPERROOT DIRECTORY
|
||||||
dnl ---------------------------------
|
dnl ---------------------------------
|
||||||
|
|
Loading…
Reference in a new issue