about summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/Zle/zle_main.c2
-rw-r--r--Src/builtin.c13
-rw-r--r--Src/glob.c2
-rw-r--r--Src/init.c30
-rw-r--r--Src/utils.c51
5 files changed, 60 insertions, 38 deletions
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index d8cbcb645..21ee8a4ed 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -716,7 +716,7 @@ raw_getbyte(int do_keytmout, char *cptr)
 # endif
 
 
-			callhookfunc(lwatch_funcs[i], funcargs);
+			callhookfunc(lwatch_funcs[i], funcargs, 0);
 			if (errflag) {
 			    /* No sensible way of handling errors here */
 			    errflag = 0;
diff --git a/Src/builtin.c b/Src/builtin.c
index e4ca9b3d9..adb0f6ee2 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -1087,7 +1087,6 @@ cd_try_chdir(char *pfix, char *dest, int hard)
 static void
 cd_new_pwd(int func, LinkNode dir)
 {
-    Eprog prog;
     char *new_pwd, *s;
     int dirstacksize;
 
@@ -1134,15 +1133,9 @@ cd_new_pwd(int func, LinkNode dir)
     }
 
     /* execute the chpwd function */
-    if ((prog = getshfunc("chpwd")) != &dummy_eprog) {
-	int osc = sfcontext;
-
-	fflush(stdout);
-	fflush(stderr);
-	sfcontext = SFC_HOOK;
-	doshfunc("chpwd", prog, NULL, 0, 1);
-	sfcontext = osc;
-    }
+    fflush(stdout);
+    fflush(stderr);
+    callhookfunc("chpwd", NULL, 1);
 
     dirstacksize = getiparam("DIRSTACKSIZE");
     /* handle directory stack sizes out of range */
diff --git a/Src/glob.c b/Src/glob.c
index aa0ce1ac4..394e91d01 100644
--- a/Src/glob.c
+++ b/Src/glob.c
@@ -1246,7 +1246,7 @@ zglob(LinkList list, LinkNode np, int nountok)
 			int arglen;
 
 			/* Find matching delimiters */
-			tt = get_strarg(s, &arglen, NULL);
+			tt = get_strarg(s, &arglen);
 			if (!*tt) {
 			    zerr("missing end of name");
 			    data = 0;
diff --git a/Src/init.c b/Src/init.c
index 7645af6b2..fad36bf0f 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -137,29 +137,33 @@ loop(int toplevel, int justonce)
 	}
 	if (hend(prog)) {
 	    int toksav = tok;
-	    Eprog preprog;
 
-	    if (toplevel && (preprog = getshfunc("preexec")) != &dummy_eprog) {
+	    if (toplevel &&
+		(getshfunc("preexec") != &dummy_eprog ||
+		 paramtab->getnode(paramtab, "preexec_functions"))) {
 		LinkList args;
-		int osc = sfcontext;
 		char *cmdstr;
 
-		args = znewlinklist();
-		zaddlinknode(args, "preexec");
+		/*
+		 * As we're about to freeheap() or popheap()
+		 * anyway, there's no gain in using permanent
+		 * storage here.
+		 */
+		args = newlinklist();
+		addlinknode(args, "preexec");
 		/* If curline got dumped from the history, we don't know
 		 * what the user typed. */
 		if (hist_ring && curline.histnum == curhist)
-		    zaddlinknode(args, hist_ring->node.nam);
+		    addlinknode(args, hist_ring->node.nam);
 		else
-		    zaddlinknode(args, "");
-		zaddlinknode(args, getjobtext(prog, NULL));
-		zaddlinknode(args, cmdstr = getpermtext(prog, NULL));
+		    addlinknode(args, "");
+		addlinknode(args, dupstring(getjobtext(prog, NULL)));
+		addlinknode(args, cmdstr = getpermtext(prog, NULL));
+
+		callhookfunc("preexec", args, 1);
 
-		sfcontext = SFC_HOOK;
-		doshfunc("preexec", preprog, args, 0, 1);
-		sfcontext = osc;
+		/* The only permanent storage is from getpermtext() */
 		zsfree(cmdstr);
-		freelinklist(args, (FreeFunc) NULL);
 		errflag = 0;
 	    }
 	    if (stopmsg)	/* unset 'you have stopped jobs' flag */
diff --git a/Src/utils.c b/Src/utils.c
index ed4abe3f1..5b6998950 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -1079,28 +1079,53 @@ time_t lastmailcheck;
 /**/
 time_t lastwatch;
 
+/*
+ * Call a function given by "name" with optional arguments
+ * "lnklist".  If "arrayp" is not zero, we also look through
+ * the array "name"_functions and execute functions found there.
+ */
+
 /**/
 mod_export int
-callhookfunc(char *name, LinkList lnklst)
+callhookfunc(char *name, LinkList lnklst, int arrayp)
 {
     Eprog prog;
-
-    if ((prog = getshfunc(name)) != &dummy_eprog) {
 	/*
 	 * Save stopmsg, since user doesn't get a chance to respond
 	 * to a list of jobs generated in a hook.
 	 */
-	int osc = sfcontext, osm = stopmsg;
+    int osc = sfcontext, osm = stopmsg, stat = 1;
+
+    sfcontext = SFC_HOOK;
 
-	sfcontext = SFC_HOOK;
+    if ((prog = getshfunc(name)) != &dummy_eprog) {
 	doshfunc(name, prog, lnklst, 0, 1);
-	sfcontext = osc;
-	stopmsg = osm;
+	stat = 0;
+    }
 
-	return 0;
+    if (arrayp) {
+	char **arrptr;
+	int namlen = strlen(name);
+#define HOOK_SUFFIX	"_functions"
+#define HOOK_SUFFIX_LEN	11	/* including NUL byte */
+	VARARR(char, arrnam, namlen + HOOK_SUFFIX_LEN);
+	memcpy(arrnam, name, namlen);
+	memcpy(arrnam + namlen, HOOK_SUFFIX, HOOK_SUFFIX_LEN);
+
+	if ((arrptr = getaparam(arrnam))) {
+	    for (; *arrptr; arrptr++) {
+		if ((prog = getshfunc(*arrptr)) != &dummy_eprog) {
+		    doshfunc(arrnam, prog, lnklst, 0, 1);
+		    stat = 0;
+		}
+	    }
+	}
     }
 
-    return 1;
+    sfcontext = osc;
+    stopmsg = osm;
+
+    return stat;
 }
 
 /* do pre-prompt stuff */
@@ -1136,15 +1161,15 @@ preprompt(void)
 
     /* If a shell function named "precmd" exists, *
      * then execute it.                           */
-    callhookfunc("precmd", NULL);
+    callhookfunc("precmd", NULL, 1);
     if (errflag)
 	return;
 
-    /* If 1) the parameter PERIOD exists, 2) the shell function     *
+    /* If 1) the parameter PERIOD exists, 2) a hook function for    *
      * "periodic" exists, 3) it's been greater than PERIOD since we *
-     * executed "periodic", then execute it now.                    */
+     * executed any such hook, then execute it now.                 */
     if (period && (time(NULL) > lastperiodic + period) &&
-	!callhookfunc("periodic", NULL))
+	!callhookfunc("periodic", NULL, 1))
 	lastperiodic = time(NULL);
     if (errflag)
 	return;