about summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2003-11-14 17:30:07 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2003-11-14 17:30:07 +0000
commit991c83ab343917b904ed7fd47a39e8517e15dcd1 (patch)
tree06dbb4726cfe75ef04878b1145de32c616f2aa84 /Src
parentf15627d17b8bbf8c6c3623844be509b544d8a9f6 (diff)
downloadzsh-991c83ab343917b904ed7fd47a39e8517e15dcd1.tar.gz
zsh-991c83ab343917b904ed7fd47a39e8517e15dcd1.tar.xz
zsh-991c83ab343917b904ed7fd47a39e8517e15dcd1.zip
19105 shout if interactive without terminal.
19167: BRACE_CCL range with NULL at start.
19168: Sizes using ztrftime were inconsistent.
Ports from main line.
Diffstat (limited to 'Src')
-rw-r--r--Src/glob.c11
-rw-r--r--Src/init.c20
-rw-r--r--Src/jobs.c5
-rw-r--r--Src/prompt.c11
-rw-r--r--Src/utils.c68
5 files changed, 93 insertions, 22 deletions
diff --git a/Src/glob.c b/Src/glob.c
index 082eea380..c0c75624e 100644
--- a/Src/glob.c
+++ b/Src/glob.c
@@ -1748,12 +1748,13 @@ xpandbraces(LinkList list, LinkNode *np)
 	 * set of flags saying whether each character is present; *
 	 * the final list is in lexical order.                    */
 	char ccl[256], *p;
-	unsigned char c1, c2, lastch;
+	unsigned char c1, c2;
 	unsigned int len, pl;
+	int lastch = -1;
 
 	uremnode(list, node);
 	memset(ccl, 0, sizeof(ccl) / sizeof(ccl[0]));
-	for (p = str + 1, lastch = 0; p < str2;) {
+	for (p = str + 1; p < str2;) {
 	    if (itok(c1 = *p++))
 		c1 = ztokens[c1 - STOUC(Pound)];
 	    if ((char) c1 == Meta)
@@ -1762,10 +1763,10 @@ xpandbraces(LinkList list, LinkNode *np)
 		c2 = ztokens[c2 - STOUC(Pound)];
 	    if ((char) c2 == Meta)
 		c2 = 32 ^ p[1];
-	    if (c1 == '-' && lastch && p < str2 && (int)lastch <= (int)c2) {
-		while ((int)lastch < (int)c2)
+	    if (c1 == '-' && lastch >= 0 && p < str2 && lastch <= (int)c2) {
+		while (lastch < (int)c2)
 		    ccl[lastch++] = 1;
-		lastch = 0;
+		lastch = -1;
 	    } else
 		ccl[lastch = c1] = 1;
 	}
diff --git a/Src/init.c b/Src/init.c
index 291351b9d..32fd41c9a 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -382,7 +382,13 @@ init_io(void)
 #endif
 
     if (shout) {
-	fclose(shout);
+	/*
+	 * Check if shout was set to stderr, if so don't close it.
+	 * We do this if we are interactive but don't have a
+	 * terminal.
+	 */
+	if (shout != stderr)
+	    fclose(shout);
 	shout = 0;
     }
     if (SHTTY != -1) {
@@ -451,9 +457,9 @@ init_io(void)
 
     /* We will only use zle if shell is interactive, *
      * SHTTY != -1, and shout != 0                   */
-    if (interact && SHTTY != -1) {
+    if (interact) {
 	init_shout();
-	if(!shout)
+	if(!SHTTY || !shout)
 	    opts[USEZLE] = 0;
     } else
 	opts[USEZLE] = 0;
@@ -486,6 +492,14 @@ mod_export void
 init_shout(void)
 {
     static char shoutbuf[BUFSIZ];
+
+    if (SHTTY == -1)
+    {
+	/* Since we're interative, it's nice to have somewhere to write. */
+	shout = stderr;
+	return;
+    }
+
 #if defined(JOB_CONTROL) && defined(TIOCSETD) && defined(NTTYDISC)
     int ldisc = NTTYDISC;
 
diff --git a/Src/jobs.c b/Src/jobs.c
index 120e4a8e6..4912ac88c 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -292,8 +292,9 @@ update_job(Job jn)
 	}
     }
 
-    if (shout && !ttyfrozen && !jn->stty_in_env && !zleactive &&
-	job == thisjob && !somestopped && !(jn->stat & STAT_NOSTTY))
+    if (shout && shout != stderr && !ttyfrozen && !jn->stty_in_env &&
+	!zleactive && job == thisjob && !somestopped &&
+	!(jn->stat & STAT_NOSTTY)) 
 	gettyinfo(&shttyinfo);
 
     if (isset(MONITOR)) {
diff --git a/Src/prompt.c b/Src/prompt.c
index 43dc12bee..7937bf520 100644
--- a/Src/prompt.c
+++ b/Src/prompt.c
@@ -479,18 +479,23 @@ putpromptchar(int doprint, int endchar)
 			tmfmt = "%m/%d/%y";
 			break;
 		    case 'D':
-			if (fm[1] == '{') /*}*/ {
+			if (fm[1] == '{' /*}*/) {
 			    for (ss = fm + 2; *ss && *ss != /*{*/ '}'; ss++)
 				if(*ss == '\\' && ss[1])
 				    ss++;
 			    dd = tmfmt = tmbuf = zalloc(ss - fm);
-			    for (ss = fm + 2; *ss && *ss != /*{*/ '}'; ss++) {
+			    for (ss = fm + 2; *ss && *ss != /*{*/ '}';
+				 ss++) {
 				if(*ss == '\\' && ss[1])
 				    ss++;
 				*dd++ = *ss;
 			    }
 			    *dd = 0;
 			    fm = ss - !*ss;
+			    if (!*tmfmt) {
+				free(tmbuf);
+				continue;
+			    }
 			} else
 			    tmfmt = "%y-%m-%d";
 			break;
@@ -502,7 +507,7 @@ putpromptchar(int doprint, int endchar)
 		    tm = localtime(&timet);
 		    for(t0=80; ; t0*=2) {
 			addbufspc(t0);
-			if(ztrftime(bp, t0, tmfmt, tm) != t0)
+			if (ztrftime(bp, t0, tmfmt, tm))
 			    break;
 		    }
 		    bp += strlen(bp);
diff --git a/Src/utils.c b/Src/utils.c
index cf202009f..fafdd99d9 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -1660,20 +1660,42 @@ spckword(char **s, int hist, int cmd, int ask)
     }
 }
 
+/*
+ * Helper for ztrftime.  Called with a pointer to the length left
+ * in the buffer, and a new string length to decrement from that.
+ * Returns 0 if the new length fits, 1 otherwise.  We assume a terminating
+ * NUL and return 1 if that doesn't fit.
+ */
+
+/**/
+static int
+ztrftimebuf(int *bufsizeptr, int decr)
+{
+    if (*bufsizeptr <= decr)
+	return 1;
+    *bufsizeptr -= decr;
+    return 0;
+}
+
+/*
+ * Like the system function, this returns the number of characters
+ * copied, not including the terminating NUL.  This may be zero
+ * if the string didn't fit.
+ */
+
 /**/
 mod_export int
 ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm)
 {
-    int hr12;
+    int hr12, decr;
 #ifndef HAVE_STRFTIME
     static char *astr[] =
     {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
     static char *estr[] =
     {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
      "Aug", "Sep", "Oct", "Nov", "Dec"};
-#else
-    char *origbuf = buf;
 #endif
+    char *origbuf = buf;
     char tmp[3];
 
 
@@ -1682,6 +1704,14 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm)
     while (*fmt)
 	if (*fmt == '%') {
 	    fmt++;
+	    /*
+	     * Assume this format will take up at least two
+	     * characters.  Not always true, but if that matters
+	     * we are so close to the edge it's not a big deal.
+	     * Fix up some longer cases specially when we get to them.
+	     */
+	    if (ztrftimebuf(&bufsize, 2))
+		return 0;
 	    switch (*fmt++) {
 	    case 'd':
 		*buf++ = '0' + tm->tm_mday / 10;
@@ -1709,9 +1739,10 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm)
 		if (hr12 == 0)
 		    hr12 = 12;
 	        if (hr12 > 9)
-		  *buf++ = '1';
+		    *buf++ = '1';
 		else if (fmt[-1] == 'l')
-		  *buf++ = ' ';
+		    *buf++ = ' ';
+
 		*buf++ = '0' + (hr12 % 10);
 		break;
 	    case 'm':
@@ -1730,11 +1761,20 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm)
 		*buf++ = '0' + (tm->tm_year / 10) % 10;
 		*buf++ = '0' + tm->tm_year % 10;
 		break;
+	    case '\0':
+		/* Guard against premature end of string */
+		*buf++ = '%';
+		fmt--;
+		break;
 #ifndef HAVE_STRFTIME
 	    case 'a':
+		if (ztrftimebuf(&bufsize, strlen(astr[tm->tm_wday]) - 2))
+		    return 0;
 		strucpy(&buf, astr[tm->tm_wday]);
 		break;
 	    case 'b':
+		if (ztrftimebuf(&bufsize, strlen(estr[tm->tm_mon]) - 2))
+		    return 0;
 		strucpy(&buf, estr[tm->tm_mon]);
 		break;
 	    case 'p':
@@ -1747,17 +1787,27 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm)
 		    *buf++ = fmt[-1];
 #else
 	    default:
+		/*
+		 * Remember we've already allowed for two characters
+		 * in the accounting in bufsize (but nowhere else).
+		 */
 		*buf = '\0';
 		tmp[1] = fmt[-1];
-		strftime(buf, bufsize - strlen(origbuf), tmp, tm);
-		buf += strlen(buf);
+		if (!strftime(buf, bufsize + 2, tmp, tm))
+		    return 0;
+		decr = strlen(buf);
+		buf += decr;
+		bufsize -= decr - 2;
 #endif
 		break;
 	    }
-	} else
+	} else {
+	    if (ztrftimebuf(&bufsize, 1))
+		return 0;
 	    *buf++ = *fmt++;
+	}
     *buf = '\0';
-    return 0;
+    return buf - origbuf;
 }
 
 /**/