buflen = 64; Newx(buf, buflen, char); len = strftime(buf, buflen, fmt, &mytm); /* ** The following is needed to handle to the situation where ** tmpbuf overflows. Basically we want to allocate a buffer ** and try repeatedly. The reason why it is so complicated ** is that getting a return value of 0 from strftime can indicate ** one of the following: ** 1. buffer overflowed, ** 2. illegal conversion specifier, or ** 3. the format string specifies nothing to be returned(not ** an error). This could be because format is an empty string ** or it specifies %p that yields an empty string in some locale. ** If there is a better way to make it portable, go ahead by ** all means. */ if ((len > 0 && len < buflen) || (len == 0 && *fmt == '\0')) return buf; else { /* Possibly buf overflowed - try again with a bigger buf */ const int fmtlen = strlen(fmt); int bufsize = fmtlen + buflen; Newx(buf, bufsize, char); while (buf) { buflen = strftime(buf, bufsize, fmt, &mytm); if (buflen > 0 && buflen < bufsize) break; /* heuristic to prevent out-of-memory errors */ if (bufsize > 100*fmtlen) { Safefree(buf); buf = NULL; break; } bufsize *= 2; Renew(buf, bufsize, char); } return buf; } #