mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-06-16 08:48:06 +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>
|
||||
|
||||
* 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
|
||||
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)
|
||||
item(tt(ZSH_NAME))(
|
||||
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;
|
||||
|
||||
/* original argv[0]. 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)
|
||||
|
|
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")
|
||||
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 ---------------------------------
|
||||
|
|
Loading…
Reference in a new issue