summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/conf.h6
-rw-r--r--src/main.c15
2 files changed, 18 insertions, 3 deletions
diff --git a/src/conf.h b/src/conf.h
index d0322cc..8a62c20 100644
--- a/src/conf.h
+++ b/src/conf.h
@@ -123,4 +123,10 @@
#define DEFAULT_FONT "-*-fixed-bold-r-normal-*-15-*-*-*-c-*-*-*"
#define BACKUP_FONT "*"
+/* maximum xvsprintf result string length for systems with pre-C99 snprintf:
+ * on errors that are either permanent or cannot be distinguished from those
+ * as libc's snprintf might by returning -1 for too small buffers, at most
+ * the double of this value is tried before giving up */
+#define MAX_LEGACY_SNPRINTF_SIZE 102400
+
#endif /* !_ _RATPOISON_CONF_H */
diff --git a/src/main.c b/src/main.c
index 7c7b468..933decb 100644
--- a/src/main.c
+++ b/src/main.c
@@ -126,15 +126,24 @@ xvsprintf (char *fmt, va_list ap)
return buffer;
else if (nchars > -1)
size = nchars + 1;
- else
+ /* c99 says -1 is an error other than truncation,
+ * which thus will not go away with a larger buffer.
+ * To support older system but not making errors fatal
+ * (ratpoison will abort when trying to get too much memory otherwise),
+ * try to increase a bit but not too much: */
+ else if (size < MAX_LEGACY_SNPRINTF_SIZE)
size *= 2;
+ else
+ {
+ free(buffer);
+ break;
+ }
/* Resize the buffer and try again. */
buffer = (char *)xrealloc (buffer, size);
}
- /* Never gets here. */
- return NULL;
+ return xstrdup("<FAILURE>");
}
/* Return a new string based on fmt. */