From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.3 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 17032 invoked from network); 4 Apr 2023 16:24:46 -0000 Received: from zero.zsh.org (2a02:898:31:0:48:4558:7a:7368) by inbox.vuxu.org with ESMTPUTF8; 4 Apr 2023 16:24:46 -0000 ARC-Seal: i=1; cv=none; a=rsa-sha256; d=zsh.org; s=rsa-20210803; t=1680625486; b=qeJTNUsUqSG9JCNVcig4A2l2EpPjZCfSPRTBtsAFukY6I7LYsL5Z18+r5UnZ1Oh87xJ7KQWxHP JZQWAM1OAf4nVcpPFuzmXNsuF2swHPfmw02qG/YTcZkPuAlY97wnK9EhBjv+fgsm5bJW+lGg5m kOYj1rR6M3+OvFHsgw2ZBm1smy52TKoSGhMbNrq0VeKg+ziV5CWl6v/WJlyt3/lYsP6pEiR4Uy Jve9XTgQBJA/3SxKOBEtsiQdICXidMC6oHMLIwkBxMNJOfiAJxbuX9yGwsEUXRKH32gAUmPH90 MmEowAu6aJ6k3TZXcV+9tEvFrfla1jbK2jZn1n3zUwJXgA==; ARC-Authentication-Results: i=1; zsh.org; iprev=pass (snd00009-bg.im.kddi.ne.jp) smtp.remote-ip=27.86.113.9; dmarc=none header.from=kba.biglobe.ne.jp; arc=none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed; d=zsh.org; s=rsa-20210803; t=1680625486; bh=G11nYuaCJvNX2WykCDspl4H0aiM/CVTBV4hRDly8X2c=; h=List-Archive:List-Owner:List-Post:List-Unsubscribe:List-Subscribe:List-Help: List-Id:Sender:Message-ID:In-Reply-To:To:References:Date:Subject: MIME-Version:Content-Transfer-Encoding:Content-Type:From:DKIM-Signature; b=dCp5Kr66EwSMa7xugUJc8z4VZyI5ZD4tUNEsg2cyCTycjbUvv7BtSlb782dMTwNgeFbM2tNJyr ftql+DjJ3YlceU0bIZ7fdOO8hOrSy2rpnZ5Zvjrb8suSldhvnDZx9BMTNGPK47t/OJTgleNK7d WrhBJRHugClEc3cA6/+idmx61jCLILoy2t4klJgeo4zQiBCXLi1mudMrCQwH3wnSrmmEXFc2K3 uLiNzGl2WLsQJ31/5+/JB+xKeoLdlMlnRz9N+E+dN6R/Fdqf2wOYUBxr1B/bphN76VNAeHASiN gqPGFXbM4VN3xlC2aMipdx3ie8CBmeewEaMQFjrtwvNmfw==; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=zsh.org; s=rsa-20210803; h=List-Archive:List-Owner:List-Post:List-Unsubscribe: List-Subscribe:List-Help:List-Id:Sender:Message-Id:In-Reply-To:To:References: Date:Subject:Mime-Version:Content-Transfer-Encoding:Content-Type:From: Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID; bh=ly8ygYFrXo/br7p+hWKJV+z1foOmfHJDcfJRraqfTys=; b=Qzo/jLCT1bEqxVqGe/NLZX4Shr G9lQTCnl+QnVJLntIHv81j0CRPhDCaFOSpcW+x6MBqKhixWjoI2ZKCL8dCb0hcKrpeU7KeCM00MWL 8ONLCE7DpT+aSMurZJ9pRL8tLxCqUMUEA7TUttd/VHwqqEuG0xGQ7TQ8Vp/UKP6OoV8ZeQ+e5oWwb Z0ZSU2FdzeeLr8sD+jPLBY6ySpO3UQryFDoOLIecgTp3xSS60qlw5Fw8rZmokTmlcO50xw/es4XWr /VxT6wY3LLOvnr6mnP5vFU7A1pBXeUR9tlrfA+A26R6DCN54412y6wUoQCeGuDZZPjH6fZWncZbHT geKr9rug==; Received: by zero.zsh.org with local id 1pjjSe-000Clu-Tz; Tue, 04 Apr 2023 16:24:45 +0000 Authentication-Results: zsh.org; iprev=pass (snd00009-bg.im.kddi.ne.jp) smtp.remote-ip=27.86.113.9; dmarc=none header.from=kba.biglobe.ne.jp; arc=none Received: from snd00009-bg.im.kddi.ne.jp ([27.86.113.9]:34913 helo=dfmta0003.biglobe.ne.jp) by zero.zsh.org with esmtps (TLS1.3:TLS_AES_256_GCM_SHA384:256) id 1pjjSL-000CTz-7t; Tue, 04 Apr 2023 16:24:27 +0000 Received: from mail.biglobe.ne.jp by omta0003.biglobe.ne.jp with ESMTP id <20230404162414241.VBSN.20034.mail.biglobe.ne.jp@biglobe.ne.jp> for ; Wed, 5 Apr 2023 01:24:14 +0900 From: "Jun. T" Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3696.120.41.1.2\)) Subject: Re: ksh compatibility: initial value of $_ Date: Wed, 5 Apr 2023 01:24:13 +0900 References: To: zsh-workers@zsh.org In-Reply-To: Message-Id: <2A0716F2-F80B-4357-87AA-0A9881A52CEC@kba.biglobe.ne.jp> X-Mailer: Apple Mail (2.3696.120.41.1.2) X-Biglobe-Sender: takimoto-j@kba.biglobe.ne.jp X-Seq: 51625 Archived-At: X-Loop: zsh-workers@zsh.org Errors-To: zsh-workers-owner@zsh.org Precedence: list Precedence: bulk Sender: zsh-workers-request@zsh.org X-no-archive: yes List-Id: List-Help: , List-Subscribe: , List-Unsubscribe: , List-Post: List-Owner: List-Archive: > 2023/04/04 1:50, Bart Schaefer wrote: >=20 > On Mon, Apr 3, 2023 at 5:14=E2=80=AFAM Jun. T = wrote: >=20 >> There may be a situation where a script >> wants to know the pathname of itself, but for almost always >> it would not be necessary to distinguish the above two cases. >=20 > ... we already have $ZSH_SCRIPT for that if portability is not an = issue. $ZSH_SCRIPT may not be the absolute pathname, but: >> But probably compatibility with other shells would be more >> important? Then guessing executable/script name only if >> $_ does not exist in environment would be the way to go. >=20 > This is my feeling as well. The following is my revised path. # Since $_ is almost always set in environment (though sometimes # not useful), this may be going too far (or to excess, don't know # the correct words). To test getmypath() we need to explicitly unset _ before starting zsh: zsh% sh # sh on Ubuntu is symlink so dash $ unset _ $ zsh -fc 'echo $_' /path/to/zsh Or zsh% env -i zsh -f foo # 'foo' contains 'echo $_' /path/to/foo diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index 528c27f93..9e9aa724f 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -779,7 +779,11 @@ last pipeline. ) vindex(_) item(tt(_) )( -The last argument of the previous command. +Initially, this parameter is set to the full pathname of the current +zsh executable or the script command file. If tt(_) already exists in = the +environment then its value is copied to this parameter; otherwise +the full pathname is inferred from the argument list. +Later, this parameter is set to the last argument of the previous = command. Also, this parameter is set in the environment of every command executed to the full pathname of the command. ) diff --git a/Src/init.c b/Src/init.c index 68621a0ad..f9240eb16 100644 --- a/Src/init.c +++ b/Src/init.c @@ -246,6 +246,9 @@ loop(int toplevel, int justonce) =20 static int restricted; =20 +/* 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 =3D=3D '-') flags |=3D PARSEARGS_LOGIN; =20 - argzero =3D posixzero =3D *argv++; + argv0 =3D argzero =3D posixzero =3D *argv++; SHIN =3D 0; =20 /* @@ -893,6 +896,117 @@ init_term(void) return 1; } =20 +/* + * Get (or guess) the absolute pathname of myself. + * If scriptname is non-NULL, guess its absolute pathname. + * Otherwise, get the absolute pathname of the current zsh executable = by OS- + * specific method, and if it fails, guess the absolute pathname of = exename. + * exename, scriptname and cwd are all unmetafied. + * Returns a zalloc()ed string, or NULL if failed. + */ +#ifdef __APPLE__ +#include +#endif + +/**/ +static char * +getmypath(const char *exename, const char *scriptname, const char *cwd) +{ + char *buf; + const char *name; + int isscript, namelen; + + if (!scriptname) { + isscript =3D 0; + buf =3D (char *)zalloc(PATH_MAX); + name =3D exename; + if (name && *name =3D=3D '-') + ++name; +#if defined(__APPLE__) + { + uint32_t n =3D PATH_MAX; + int ret; + if ((ret =3D _NSGetExecutablePath(buf, &n)) < 0) { + /* try again with increased buffer size */ + free(buf); + buf =3D (char *)zalloc(n); + ret =3D _NSGetExecutablePath(buf, &n); + } + if (ret =3D=3D 0 && strlen(buf) > 0) + return buf; + } +#elif defined(PROC_SELF_EXE) + { + ssize_t n; + n =3D readlink(PROC_SELF_EXE, buf, PATH_MAX); + if (n > 0 && n < PATH_MAX) { + buf[n] =3D '\0'; + return buf; + } + } +#endif + free(buf); + } + else { + isscript =3D 1; + name =3D scriptname; + } + + /* guess the absolute pathname of 'name' */ + namelen =3D strlen(name); + if (namelen =3D=3D 0) + return NULL; + else if (name[namelen-1] =3D=3D '/') /* name should not end with = '/' */ + return NULL; + else if (name[0] =3D=3D '/') { + /* name is already an absolute pathname */ + buf =3D (char *)zalloc(namelen + 1); + strcpy(buf, name); + return buf; + } + else if (isscript || strchr(name, '/')) { + /* relative path */ + if (!cwd) + return NULL; + buf =3D (char *)zalloc(strlen(cwd) + namelen + 2); + strcpy(buf, cwd); + strcat(buf, "/"); + strcat(buf, name); + return buf; + } +#ifdef HAVE_REALPATH + else { + /* search each dir in PARH */ + const char *path, *sep; + char *real, *try; + int pathlen, dirlen; + + path =3D getenv("PATH"); + if (!path || (pathlen =3D strlen(path)) =3D=3D 0) + return NULL; + /* for simplicity, allocate buf even if REALPATH_ACCEPTS_NULL is = on */ + buf =3D (char *)zalloc(PATH_MAX); + try =3D (char *)zalloc(pathlen + namelen + 2); + do { + sep =3D strchr(path, ':'); + dirlen =3D sep ? sep - path : strlen(path); + strncpy(try, path, dirlen); + try[dirlen] =3D '/'; + try[dirlen+1] =3D '\0'; + strcat(try, name); + real =3D realpath(try, buf); + if (sep) + path =3D 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 */ =20 /**/ @@ -1084,9 +1198,6 @@ setupvals(char *cmd, char *runscript, char = *zsh_name) ztrdup(DEFAULT_IFS_SH) : ztrdup(DEFAULT_IFS); wordchars =3D ztrdup(DEFAULT_WORDCHARS); postedit =3D ztrdup(""); - zunderscore =3D (char *) zalloc(underscorelen =3D 32); - underscoreused =3D 1; - *zunderscore =3D '\0'; =20 zoptarg =3D ztrdup(""); zoptind =3D 1; @@ -1138,6 +1249,30 @@ setupvals(char *cmd, char *runscript, char = *zsh_name) =20 oldpwd =3D ztrdup(pwd); /* initialize `OLDPWD' =3D `PWD' */ =20 + /* initialize $_. If $_ is set in environment then use it. + * Otherwise guess from runscript or argv0. */ + zunderscore =3D getenv("_"); + if (zunderscore && *zunderscore) { + zunderscore =3D metafy(ztrdup(zunderscore), -1, META_REALLOC); + } + else { + char *exename, *scriptname, *cwd; + exename =3D unmetafy(ztrdup(argv0), NULL); + scriptname =3D runscript ? unmetafy(ztrdup(runscript), NULL) : = NULL; + cwd =3D pwd ? unmetafy(ztrdup(pwd), NULL) : NULL; + zunderscore =3D getmypath(exename, scriptname, cwd); + free(exename); + free(scriptname); + free(cwd); + if (zunderscore) + zunderscore =3D metafy(zunderscore, -1, META_REALLOC); + } + if (!zunderscore) + zunderscore =3D ztrdup(""); + underscoreused =3D strlen(zunderscore) + 1; + underscorelen =3D (underscoreused + 31) & ~31; + zunderscore =3D (char *)zrealloc(zunderscore, underscorelen); + inittyptab(); /* initialize the ztypes table */ initlextabs(); /* initialize lexing tables */ =20 diff --git a/configure.ac b/configure.ac index e6ced85d9..d33ea6945 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -dnl +dnexe dnl configure.ac: Configure template for zsh. dnl Process this file with autoconf to produce a configure script. dnl @@ -2011,6 +2011,25 @@ if test x$zsh_cv_sys_path_dev_fd !=3D xno; then AC_DEFINE_UNQUOTED(PATH_DEV_FD, "$zsh_cv_sys_path_dev_fd") fi =20 +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 + readlink $zsh_cv_proc_self_exe >/dev/null && break +done]) +if test x$zsh_cv_proc_self_exe !=3D xno; then + AC_DEFINE_UNQUOTED(PROC_SELF_EXE, "$zsh_cv_proc_self_exe") +fi + dnl --------------------------------- dnl CHECK FOR RFS SUPERROOT DIRECTORY dnl ---------------------------------