zsh-workers
 help / color / mirror / Atom feed
* [PATCH] Re: chpwd, precmd hooks have "zsh" in $0
       [not found]       ` <YRSmIo0N4vu3zZ4h@isis.sigpipe.cz>
@ 2021-08-15  1:21         ` Bart Schaefer
  2021-08-15  5:00           ` Bart Schaefer
  0 siblings, 1 reply; 2+ messages in thread
From: Bart Schaefer @ 2021-08-15  1:21 UTC (permalink / raw)
  To: Roman Neuhauser; +Cc: Zsh hackers list

[-- Attachment #1: Type: text/plain, Size: 2987 bytes --]

Moving discussion to zsh-workers.

On Wed, Aug 11, 2021 at 9:40 PM Roman Neuhauser <neuhauser@sigpipe.cz> wrote:
>
> # schaefer@brasslantern.com / 2021-08-10 10:31:00 -0700:
> >
> > Theoretically, a function might prefer to know that it was being
> > called as a consequence of being found in a given hook list, vs. being
> > called directly.  That might argue for [calling all with the hookname].
>
> yes, but there's other ways to let a function know it's being called as
> part of a particular hook array.  there's only one reasonable way
> of letting a function know the name it was called with.

Attached patch implements calling hook functions with $0 as their own
name, even in the hook arrays.  If there's a better way to
nondestructively copy the tail of a LinkList, please tell me.

In order to do this for functions that already get an argument list
(preexec and zshaddhistory, for example) I had to modify
callhookfunc(), so I did NOT change doshfunc(), which means the
behavior of zftp callbacks is unchanged and will have to be addressed
separately.

> > >     function a b { ... } > ab.log
> > >     precmd_functions=(a)
> > >     preexec_functions=(b)
> > >
> > > calls the function with $0 == "a" in precmd, "b" in preexec,
> > > and that their runtime output goes to ab.log.  hooks do neither
> > > and TRAPNAL functions only [use ...]
> [...] the correct name for a function defined with multiple names.

So I dug a little further into why this happens (that is, why
redirection does NOT) and found that it's because doshfunc() extracts
the function body and jumps directly to the first command in the body
via runshfunc(), thereby skipping the redirections, which are normally
handled by execcmd_exec() after the function object is looked up
there.

I haven't verified it, but I believe this also means that "sticky"
emulations are not honored by functions called as hooks (and various
other entry points that call doshfunc() directly).

There's a chicken-and-egg problem here because execcmd_exec() itself
eventually runs shell functions by calling execshfunc() which then
calls doshfunc(), so we can't push the redirection handling down into
doshfunc() ... the order of events for forks and subshells would
become wrong.

One obvious way to fix this -- and I vaguely recall this having been
suggested during the discussion back in 2014 -- is to dispose of the
Eprog redir from struct shfunc and instead change the parser to push
the redirections onto the Eprog funcdef -- in effect, convert at parse
time
   func() { ... } > file
into
   function func { { ... } > file }

What the equivalent is for sticky emulations, I don't know.

Another way to fix it might be to change the call signature of
doshfunc() to include a flag that says whether to process redirections
[and sticky emulations] and then copy code from execmd_exec() that
would be run when that flag is true.  I'm not sure what the
consequences are in terms of correctly unwinding state in those cases.

[-- Attachment #2: callhookfunc_arg0.txt --]
[-- Type: text/plain, Size: 1455 bytes --]

diff --git a/Src/utils.c b/Src/utils.c
index 5a9222919..c32741ca7 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -1498,7 +1498,7 @@ time_t lastwatch;
 
 /*
  * Call a function given by "name" with optional arguments
- * "lnklist".  If these are present the first argument is the function name.
+ * "lnklst".  If these are present the first argument is the function name.
  *
  * If "arrayp" is not zero, we also look through
  * the array "name"_functions and execute functions found there.
@@ -1527,6 +1527,10 @@ callhookfunc(char *name, LinkList lnklst, int arrayp, int *retval)
     incompfunc = 0;
 
     if ((shfunc = getshfunc(name))) {
+	if (!lnklst) {
+	    lnklst = newlinklist();
+	    addlinknode(lnklst, name);
+	}
 	ret = doshfunc(shfunc, lnklst, 1);
 	stat = 0;
     }
@@ -1539,10 +1543,16 @@ callhookfunc(char *name, LinkList lnklst, int arrayp, int *retval)
 	memcpy(arrnam + namlen, HOOK_SUFFIX, HOOK_SUFFIX_LEN);
 
 	if ((arrptr = getaparam(arrnam))) {
+	    char **argarr = lnklst ? hlinklist2array(lnklst, 0) : NULL;
 	    arrptr = arrdup(arrptr);
 	    for (; *arrptr; arrptr++) {
 		if ((shfunc = getshfunc(*arrptr))) {
-		    int newret = doshfunc(shfunc, lnklst, 1);
+		    int newret, i = 1;
+		    LinkList arg0 = newlinklist();
+		    addlinknode(arg0, *arrptr);
+		    while (argarr && argarr[i])
+			addlinknode(arg0, argarr[i++]);
+		    newret = doshfunc(shfunc, arg0, 1);
 		    if (!ret)
 			ret = newret;
 		    stat = 0;

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Re: chpwd, precmd hooks have "zsh" in $0
  2021-08-15  1:21         ` [PATCH] Re: chpwd, precmd hooks have "zsh" in $0 Bart Schaefer
@ 2021-08-15  5:00           ` Bart Schaefer
  0 siblings, 0 replies; 2+ messages in thread
From: Bart Schaefer @ 2021-08-15  5:00 UTC (permalink / raw)
  To: Roman Neuhauser; +Cc: Zsh hackers list

On Sat, Aug 14, 2021 at 6:21 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
>
> I haven't verified it, but I believe this also means that "sticky"
> emulations are not honored by functions called as hooks (and various
> other entry points that call doshfunc() directly).

This turns out not to be the case, sticky emulations are handled in
doshfunc().  I should have looked for that before I spoke.


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-08-15  5:01 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <YRGM5st2N0tfvPMQ@isis.sigpipe.cz>
     [not found] ` <CAH+w=7ZjVYzE6T+9Ditnzx4EFFAy0jMzsj9sD8gDBkJW97Mjow@mail.gmail.com>
     [not found]   ` <YRJkDTl9cMxzn4Gd@isis.sigpipe.cz>
     [not found]     ` <CAH+w=7bQN-uuaW-hthX0Wi5J1mmsyB4AsWN0JP75vG0z_zwmRw@mail.gmail.com>
     [not found]       ` <YRSmIo0N4vu3zZ4h@isis.sigpipe.cz>
2021-08-15  1:21         ` [PATCH] Re: chpwd, precmd hooks have "zsh" in $0 Bart Schaefer
2021-08-15  5:00           ` Bart Schaefer

zsh-workers

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://inbox.vuxu.org/zsh-workers

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V1 zsh-workers zsh-workers/ https://inbox.vuxu.org/zsh-workers \
		zsh-workers@zsh.org
	public-inbox-index zsh-workers

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://inbox.vuxu.org/vuxu.archive.zsh.workers


code repositories for the project(s) associated with this inbox:

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

AGPL code for this site: git clone https://public-inbox.org/public-inbox.git