about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--Src/Modules/datetime.c2
-rw-r--r--Src/prompt.c13
-rw-r--r--Src/utils.c14
4 files changed, 28 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index d68b7c24d..24d870448 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2004-05-04  Peter Stephenson  <pws@csr.com>
+
+	* 19877: Src/prompt.c, Src/utils.c, Src/Modules/datetime.c:
+	Improve 19869: remove infinite loop and attempt to test
+	for whether strftime() encountered an error.
+
 2004-05-04  Clint Adams  <clint@zsh.org>
 
 	* 19869: Src/prompt.c, Src/utils.c: avoid segfault when
diff --git a/Src/Modules/datetime.c b/Src/Modules/datetime.c
index 5877b8490..cb85b8e09 100644
--- a/Src/Modules/datetime.c
+++ b/Src/Modules/datetime.c
@@ -61,7 +61,7 @@ bin_strftime(char *nam, char **argv, Options ops, int func)
     buffer = zalloc(bufsize);
 
     for (x=0; x < 4; x++) {
-        if (ztrftime(buffer, bufsize, argv[0], t))
+        if (ztrftime(buffer, bufsize, argv[0], t) >= 0)
 	    break;
 	buffer = zrealloc(buffer, bufsize *= 2);
     }
diff --git a/Src/prompt.c b/Src/prompt.c
index e0304f298..d83ec9417 100644
--- a/Src/prompt.c
+++ b/Src/prompt.c
@@ -526,11 +526,16 @@ putpromptchar(int doprint, int endchar)
 		    }
 		    timet = time(NULL);
 		    tm = localtime(&timet);
-		    for(t0=80; ; t0*=2) {
+		    /*
+		     * Hack because strftime won't say how
+		     * much space it actually needs.  Try to add it
+		     * a few times until it works.  Some formats don't
+		     * actually have a length, so we could go on for
+		     * ever.
+		     */
+		    for(j = 0, t0 = strlen(tmfmt)*8; j < 3; j++, t0*=2) {
 			addbufspc(t0);
-			if (ztrftime(bp, t0, tmfmt, tm) ||
-			    !strcmp("%P", tmfmt) ||
-			    !strcmp("%p", tmfmt))
+			if (ztrftime(bp, t0, tmfmt, tm) >= 0)
 			    break;
 		    }
 		    bp += strlen(bp);
diff --git a/Src/utils.c b/Src/utils.c
index c0a96a5b4..ee78665c1 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -1719,6 +1719,11 @@ ztrftimebuf(int *bufsizeptr, int decr)
  * 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.
+ *
+ * As an extension, try to detect an error in strftime --- typically
+ * not enough memory --- and return -1.  Not guaranteed to be portable,
+ * since the strftime() interface doesn't make any guarantees about
+ * the state of the buffer if it returns zero.
  */
 
 /**/
@@ -1831,9 +1836,14 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm)
 		 */
 		*buf = '\0';
 		tmp[1] = fmt[-1];
-		if (!strftime(buf, bufsize + 2, tmp, tm) &&
-		    tmp[1]!='p' && tmp[1]!='P')
+		if (!strftime(buf, bufsize + 2, tmp, tm))
+		{
+		    if (*buf) {
+			buf[0] = '\0';
+			return -1;
+		    }
 		    return 0;
+		}
 		decr = strlen(buf);
 		buf += decr;
 		bufsize -= decr - 2;