about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Src/exec.c45
-rw-r--r--Src/init.c3
-rw-r--r--Src/utils.c13
3 files changed, 34 insertions, 27 deletions
diff --git a/Src/exec.c b/Src/exec.c
index 61b9fe60f..d093c7701 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -1413,6 +1413,27 @@ addvars(LinkList l, int export)
 }
 
 /**/
+void
+setunderscore(char *str)
+{
+    if (str && *str) {
+	int l = strlen(str) + 1;
+
+	if (l > underscorelen || l < (underscorelen >> 2)) {
+	    zfree(underscore, underscorelen);
+	    underscore = (char *) zalloc(underscorelen = l);
+	}
+	strcpy(underscore, str);
+	underscoreused = l;
+    } else {
+	zfree(underscore, underscorelen);
+	underscore = (char *) zalloc(underscorelen = 32);
+	*underscore = '\0';
+	underscoreused = 1;
+    }
+}
+
+/**/
 static void
 execcmd(Cmd cmd, int input, int output, int how, int last1)
 {
@@ -1629,21 +1650,8 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
 	text = NULL;
 
     /* Set up special parameter $_ */
-    if (args && nonempty(args)) {
-	char *u = (char *) getdata(lastnode(args));
 
-	if (u) {
-	    int ul = strlen(u);
-
-	    if (ul >= underscorelen) {
-		zfree(underscore, underscorelen);
-		underscore = (char *) zalloc(underscorelen = ul + 32);
-	    }
-	    strcpy(underscore, u);
-	} else
-	    *underscore = '\0';
-    } else
-	*underscore = '\0';
+    setunderscore((args && nonempty(args)) ? ((char *) getdata(lastnode(args))) : "");
 
     /* Warn about "rm *" */
     if (type == SIMPLE && interact && unset(RMSTARSILENT)
@@ -3016,7 +3024,9 @@ void
 runshfunc(List list, FuncWrap wrap, char *name)
 {
     int cont;
-    VARARR(char, ou, underscorelen);
+    VARARR(char, ou, underscoreused);
+
+    memcpy(ou, underscore, underscoreused);
 
     while (wrap) {
 	wrap->module->wrapper++;
@@ -3032,9 +3042,8 @@ runshfunc(List list, FuncWrap wrap, char *name)
 	wrap = wrap->next;
     }
     startparamscope();
-    strcpy(ou, underscore);
     execlist(list, 1, 0);
-    strcpy(underscore, ou);
+    setunderscore(ou);
     endparamscope();
 }
 
@@ -3233,7 +3242,7 @@ execrestore(void)
     trapreturn = exstack->trapreturn;
     noerrs = exstack->noerrs;
     subsh_close = exstack->subsh_close;
-    strcpy(underscore, exstack->underscore);
+    setunderscore(exstack->underscore);
     zsfree(exstack->underscore);
     en = exstack->next;
     free(exstack);
diff --git a/Src/init.c b/Src/init.c
index 2761a6afc..f0b9803e4 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -43,7 +43,7 @@ int noexitct = 0;
 char *underscore;
 
 /**/
-int underscorelen;
+int underscorelen, underscoreused;
 
 /* what level of sourcing we are at */
  
@@ -625,6 +625,7 @@ setupvals(void)
     wordchars   = ztrdup(DEFAULT_WORDCHARS);
     postedit    = ztrdup("");
     underscore  = (char *) zalloc(underscorelen = 32);
+    underscoreused = 1;
     *underscore = '\0';
 
     zoptarg = ztrdup("");
diff --git a/Src/utils.c b/Src/utils.c
index 38468969e..f81ee8d5d 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -752,14 +752,11 @@ checkmailpath(char **s)
 		    fprintf(shout, "You have new mail.\n");
 		    fflush(shout);
 		} else {
-		    VARARR(char, usav, underscorelen);
-		    int sl = strlen(*s);
+		    VARARR(char, usav, underscoreused);
 
-		    if (sl >= underscorelen) {
-			zfree(underscore, underscorelen);
-			underscore = (char *) zalloc(underscorelen = sl + 32);
-		    }
-		    strcpy(underscore, *s);
+		    memcpy(usav, underscore, underscoreused);
+
+		    setunderscore(*s);
 		    HEAPALLOC {
 			u = dupstring(u);
 			if (! parsestr(u)) {
@@ -769,7 +766,7 @@ checkmailpath(char **s)
 			    fflush(shout);
 			}
 		    } LASTALLOC;
-		    strcpy(underscore, usav);
+		    setunderscore(usav);
 		}
 	    }
 	    if (isset(MAILWARNING) && st.st_atime > st.st_mtime &&