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 4522 invoked from network); 3 Apr 2023 11:17:06 -0000 Received: from zero.zsh.org (2a02:898:31:0:48:4558:7a:7368) by inbox.vuxu.org with ESMTPUTF8; 3 Apr 2023 11:17:06 -0000 ARC-Seal: i=1; cv=none; a=rsa-sha256; d=zsh.org; s=rsa-20210803; t=1680520626; b=nyA1LrNaZEExC/lSRFeIEbtYs0CaOK05wV/eqApabECr0k2VggV2mpXhxGZIszBf9IeSo7W12l PhYhfGF4+lIE4jrwPU6tyijwlY0bm15IjKY9QjPHGaWQfXNMdEVvEzsLfjFqJ7e179NMTFmZWy bGxOGRYbE5V6tlbfewwFL4AnqkDsGXCpqx146KwMoeaV+7X+7C1V5nNXzQbAwpPDi5x1gSnysh wsIreG5d2zcsv/fa2ECD9+w/kHRtxvsK5d6Y0QdL3Aein5oBEl4kz8ZMsWtb/YabA8DgLdCfwC DXBdeNPkG5DllHOYmbV1BzGBXP4f83Lipa7eJNLbbk9hRA==; ARC-Authentication-Results: i=1; zsh.org; iprev=pass (snd00011-bg.im.kddi.ne.jp) smtp.remote-ip=27.86.113.11; 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=1680520626; bh=QRrwjRzFFcLtrSSJZ0f3GTjSAcLjDeLgzSROg5G811E=; 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=Lq9zCm2Ha2By9GPBla8+AA8A9CZWI8ciOTOfiBYDAwa9HfBBBxjTXsQ00f1vuWM26sVB6Qh/n6 VhnufGeOBa9Xg2pCHYd+8szxVq/aB6iDVYPNvGSWaAhbGtvt6KKQTSxEuLrv/j5BQNNDuE/6uZ z6ciUDegJrM1nFik0Ws6QO2aCcaSDMjzKqWEy0698l+NpneffmtAHinT/tBFKcC6IOhiJpfA4w RB8bkeFWHOgDxR0Ti5diiT6RwpG327TmrsRCqA0SwHTwG8bkMOug9AoobFs0aJvzYUV2Vk9DQM okSd39cahGvx0DUkM94rz6QwUE3NesfDAyE60Objrhi00A==; 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=P58xTriPH01zhWjlkc2g5KPVDwq7yAwjRfIwhbJAXCc=; b=ZJWxIZYpFXhE9K4ubcjRQKxGUe iRf9PqTEG/pIpfuJWQ9ad585+6+AG+fh1OtR+tQErWXqHiaMutQfPkqEz/NH8ELZGD0bBT37vkvul faZt1gnADEBY9ClsYDMpr3RdUcwpu6NDh2QE1NpmMOTLKAw1toievk9Dv/v4iMa8837ALDqlbdFh+ Bn+nemD4S4vmTVk9zhMzSECMsbdcedcZZ/aIkIU/X/l1SruYa1ow7RxAY3NvHGI+cIfdqAh6JO+R7 tvqnZBeJMJVAEWnKHf3X/Il/JrQh4VCMsr0lN0TXt3T8ZI3usJrG0P+9U3H9ke5SbeWdg+OBjalZP d5CvxD4w==; Received: by zero.zsh.org with local id 1pjIBM-000EYg-IO; Mon, 03 Apr 2023 11:17:04 +0000 Authentication-Results: zsh.org; iprev=pass (snd00011-bg.im.kddi.ne.jp) smtp.remote-ip=27.86.113.11; dmarc=none header.from=kba.biglobe.ne.jp; arc=none Received: from snd00011-bg.im.kddi.ne.jp ([27.86.113.11]:42145 helo=dfmta0002.biglobe.ne.jp) by zero.zsh.org with esmtps (TLS1.3:TLS_AES_256_GCM_SHA384:256) id 1pjIAn-000EF1-8X; Mon, 03 Apr 2023 11:16:31 +0000 Received: from mail.biglobe.ne.jp by omta0002.biglobe.ne.jp with ESMTP id <20230403111623078.TTEL.7117.mail.biglobe.ne.jp@biglobe.ne.jp> for ; Mon, 3 Apr 2023 20:16:23 +0900 From: "Jun. T" Content-Type: text/plain; charset=us-ascii 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: Mon, 3 Apr 2023 20:16:22 +0900 References: To: zsh-workers@zsh.org In-Reply-To: Message-Id: <20B96AB1-75EB-4DAD-93C5-B56A84CCA045@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: 51619 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/01 2:45, Bart Schaefer wrote: >=20 > With your patch: >=20 > % /bin/sh > $ Src/zsh -fc 'print $_' > /bin/sh > $ Src/zsh -fc 'echo $_' > print $_ > $ >=20 > Similar behavior from ksh, so it really is whatever happens to be in > the environment for '_' rather than an actual pathname. This means > you only get the documented behavior when a new shell or script was > invoked via a previous shell that exports $_ Well, I think this is _the_ behavior ksh document specifies. If what we want to achieve is just the ksh compatibility then this is enough? But of course we can do better. The patch below ignores the $_ in environment and tries to guess the executable/script pathname. (this is just a draft; it would be better to set PROC_SELF_EXE in configure if we are going to use this). Or we can use this only if $_ is not in environment (I guess bash behaves this way). diff --git a/Src/init.c b/Src/init.c index 68621a0ad..5fa8985e0 100644 --- a/Src/init.c +++ b/Src/init.c @@ -246,6 +246,9 @@ loop(int toplevel, int justonce) =20 static int restricted; =20 +/* save original argv[0] for initialization of $_ */ +static char *argv0; + /**/ static void parseargs(char *zsh_name, char **argv, char **runscript, char **cmdptr, @@ -258,6 +261,7 @@ parseargs(char *zsh_name, char **argv, char = **runscript, char **cmdptr, flags |=3D PARSEARGS_LOGIN; =20 argzero =3D posixzero =3D *argv++; + argv0 =3D unmetafy(ztrdup(argzero), NULL); SHIN =3D 0; =20 /* @@ -893,6 +897,109 @@ init_term(void) return 1; } =20 +/* + * Get (or guess) the full pathname of myself. If runscript is = non-NULL, + * use it as a script file name, and guess its full pathname. + * Otherwize, get the full pathname of the current zsh executable by + * OS-specific method, and if it fails, guess the full pathname of = argv0. + * argv0, runscript and cwd are all unmetafied. + * Returns a zalloc()ed string, or NULL if failed. + */ +#if defined(__APPLE__) +#include +#elif defined(__linux) +#define PROC_SELF_EXE "/proc/self/exe" +#endif + +/**/ +static char * +getmypath(const char *argv0, const char *runscript, const char *cwd) +{ + char *buf; + const char *name; + int isscript, namelen; + + if (!runscript) { + isscript =3D 0; + name =3D argv0; + if (name && *name =3D=3D '-') + ++name; +#if defined(__APPLE__) + unsigned int n; + int ret; + buf =3D (char *)zalloc(PATH_MAX); + n =3D PATH_MAX; + 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) + int n; + buf =3D (char *)zalloc(PATH_MAX); + 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 runscript; + } + + /* guess the full 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 a fullpath */ + buf =3D (char *)zalloc(namelen + 1); + strcpy(buf, name); + return buf; + } + else if (isscript || strchr(name, '/')) { + /* realative path */ + if (!cwd) + return NULL; + buf =3D (char *)zalloc(strlen(cwd) + namelen + 2); + strcpy(buf, cwd); + strcat(buf, "/"); + strcat(buf, name); + return buf; + } + else { + /* search each dir in PARH */ + const char *path, *sep; + char *real; + int pathlen, dirlen; + path =3D getenv("PATH"); + if (!path || (pathlen =3D strlen(path)) =3D=3D 0) + return NULL; + buf =3D (char *)zalloc(pathlen + namelen + 2); + do { + sep =3D strchr(path, ':'); + dirlen =3D sep ? sep - path : strlen(path); + strncpy(buf, path, dirlen); + buf[dirlen] =3D '/'; + buf[dirlen+1] =3D '\0'; + strcat(buf, name); + real =3D realpath(buf, NULL); + if (sep) + path =3D sep + 1; + } while (!real && sep); + free(buf); + return real; /* this may be NULL */ + } +} + /* Initialize lots of global variables and hash tables */ =20 /**/ @@ -903,7 +1010,7 @@ setupvals(char *cmd, char *runscript, char = *zsh_name) struct passwd *pswd; #endif struct timezone dummy_tz; - char *ptr; + char *ptr, *mypath; int i, j; #if defined(SITEFPATH_DIR) || defined(FPATH_DIR) || defined = (ADDITIONAL_FPATH) || defined(FIXED_FPATH_DIR) # define FPATH_NEEDS_INIT 1 @@ -1084,9 +1191,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 +1242,34 @@ setupvals(char *cmd, char *runscript, char = *zsh_name) =20 oldpwd =3D ztrdup(pwd); /* initialize `OLDPWD' =3D `PWD' */ =20 + /* initialize $_ */ + { + char *exename =3D argv0, *scriptname =3D runscript, *cwd =3D = pwd; + if (exename) + exename =3D unmetafy(ztrdup(exename), NULL); + if (scriptname) + scriptname =3D unmetafy(ztrdup(scriptname), NULL); + if (cwd) + cwd =3D unmetafy(ztrdup(cwd), NULL); + zunderscore =3D getmypath(exename, scriptname, cwd); + free(exename); + free(scriptname); + free(cwd); + } + if (zunderscore) { + zunderscore =3D metafy(zunderscore, -1, META_REALLOC); + underscoreused =3D strlen(zunderscore) + 1; + underscorelen =3D (underscoreused + 31) & ~31; + zunderscore =3D (char *)zrealloc(zunderscore, underscorelen); + } + else { + zunderscore =3D (char *) zalloc(underscorelen =3D 32); + underscoreused =3D 1; + *zunderscore =3D '\0'; + } + + + inittyptab(); /* initialize the ztypes table */ initlextabs(); /* initialize lexing tables */ =20