Git fork
at reftables-rust 69 lines 1.5 kB view raw
1#include "../git-compat-util.h" 2 3/* 4 * The size parameter specifies the available space, i.e. includes 5 * the trailing NUL byte; but Windows's vsnprintf uses the entire 6 * buffer and avoids the trailing NUL, should the buffer be exactly 7 * big enough for the result. Defining SNPRINTF_SIZE_CORR to 1 will 8 * therefore remove 1 byte from the reported buffer size, so we 9 * always have room for a trailing NUL byte. 10 */ 11#ifndef SNPRINTF_SIZE_CORR 12#if defined(WIN32) && (!defined(__GNUC__) || __GNUC__ < 4) && (!defined(_MSC_VER) || _MSC_VER < 1900) 13#define SNPRINTF_SIZE_CORR 1 14#else 15#define SNPRINTF_SIZE_CORR 0 16#endif 17#endif 18 19#undef vsnprintf 20int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap) 21{ 22 va_list cp; 23 char *s; 24 int ret = -1; 25 26 if (maxsize > 0) { 27 va_copy(cp, ap); 28 ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, cp); 29 va_end(cp); 30 if (ret == maxsize-1) 31 ret = -1; 32 /* Windows does not NUL-terminate if result fills buffer */ 33 str[maxsize-1] = 0; 34 } 35 if (ret != -1) 36 return ret; 37 38 s = NULL; 39 if (maxsize < 128) 40 maxsize = 128; 41 42 while (ret == -1) { 43 maxsize *= 4; 44 str = realloc(s, maxsize); 45 if (! str) 46 break; 47 s = str; 48 va_copy(cp, ap); 49 ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, cp); 50 va_end(cp); 51 if (ret == maxsize-1) 52 ret = -1; 53 } 54 free(s); 55 return ret; 56} 57 58int git_snprintf(char *str, size_t maxsize, const char *format, ...) 59{ 60 va_list ap; 61 int ret; 62 63 va_start(ap, format); 64 ret = git_vsnprintf(str, maxsize, format, ap); 65 va_end(ap); 66 67 return ret; 68} 69