]> git.saurik.com Git - apple/libc.git/blame - stdio/FreeBSD/vfscanf.c.patch
Libc-763.11.tar.gz
[apple/libc.git] / stdio / FreeBSD / vfscanf.c.patch
CommitLineData
1f2f436a
A
1--- vfscanf.c.orig 2010-07-15 10:03:36.000000000 -0700
2+++ vfscanf.c 2010-07-15 10:18:58.000000000 -0700
3@@ -36,6 +36,8 @@ static char sccsid[] = "@(#)vfscanf.c 8.
3d9156a7 4 #include <sys/cdefs.h>
1f2f436a 5 __FBSDID("$FreeBSD: src/lib/libc/stdio/vfscanf.c,v 1.43 2009/01/19 06:19:51 das Exp $");
3d9156a7
A
6
7+#include "xlocale_private.h"
8+
9 #include "namespace.h"
10 #include <ctype.h>
11 #include <inttypes.h>
1f2f436a 12@@ -46,6 +48,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/v
34e8f829
A
13 #include <string.h>
14 #include <wchar.h>
15 #include <wctype.h>
16+#include <pthread.h>
17 #include "un-namespace.h"
18
19 #include "collate.h"
1f2f436a 20@@ -93,9 +96,9 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/v
3d9156a7 21 #define CT_INT 3 /* %[dioupxX] conversion */
59e0d9fe
A
22 #define CT_FLOAT 4 /* %[efgEFG] conversion */
23
3d9156a7 24-static const u_char *__sccl(char *, const u_char *);
3d9156a7 25+static const u_char *__sccl(char *, const u_char *, locale_t);
1f2f436a
A
26 #ifndef NO_FLOATING_POINT
27-static int parsefloat(FILE *, char *, char *);
3d9156a7 28+static int parsefloat(FILE *, char **, size_t, locale_t);
1f2f436a 29 #endif
3d9156a7
A
30
31 __weak_reference(__vfscanf, vfscanf);
1f2f436a 32@@ -104,12 +107,24 @@ __weak_reference(__vfscanf, vfscanf);
3d9156a7
A
33 * __vfscanf - MT-safe version
34 */
35 int
36-__vfscanf(FILE *fp, char const *fmt0, va_list ap)
37+__vfscanf(FILE * __restrict fp, char const * __restrict fmt0, va_list ap)
34e8f829
A
38 {
39 int ret;
40
41 FLOCKFILE(fp);
42- ret = __svfscanf(fp, fmt0, ap);
3d9156a7
A
43+ ret = __svfscanf_l(fp, __current_locale(), fmt0, ap);
44+ FUNLOCKFILE(fp);
45+ return (ret);
46+}
47+
48+int
49+vfscanf_l(FILE * __restrict fp, locale_t loc, char const * __restrict fmt0, va_list ap)
34e8f829
A
50+{
51+ int ret;
52+
3d9156a7 53+ NORMALIZE_LOCALE(loc);
34e8f829 54+ FLOCKFILE(fp);
3d9156a7
A
55+ ret = __svfscanf_l(fp, loc, fmt0, ap);
56 FUNLOCKFILE(fp);
57 return (ret);
58 }
1f2f436a 59@@ -117,8 +132,8 @@ __vfscanf(FILE *fp, char const *fmt0, va
3d9156a7
A
60 /*
61 * __svfscanf - non-MT-safe version of __vfscanf
62 */
63-int
64-__svfscanf(FILE *fp, const char *fmt0, va_list ap)
65+__private_extern__ int
66+__svfscanf_l(FILE * __restrict fp, locale_t loc, const char * __restrict fmt0, va_list ap)
67 {
68 const u_char *fmt = (const u_char *)fmt0;
69 int c; /* character from format, or conversion */
1f2f436a 70@@ -128,36 +143,43 @@ __svfscanf(FILE *fp, const char *fmt0, v
59e0d9fe
A
71 int flags; /* flags as defined above */
72 char *p0; /* saves original value of p when necessary */
73 int nassigned; /* number of fields assigned */
74- int nconversions; /* number of conversions */
75 int nread; /* number of characters consumed from fp */
76 int base; /* base argument to conversion function */
77 char ccltab[256]; /* character class table for %[...] */
1f2f436a 78 char buf[BUF]; /* buffer for numeric and mb conversions */
3d9156a7 79 wchar_t *wcp; /* handy wide character pointer */
3d9156a7
A
80 size_t nconv; /* length of multibyte sequence converted */
81+ int index; /* %index$, zero if unset */
82+ va_list ap_orig; /* to reset ap to first argument */
83 static const mbstate_t initial;
84 mbstate_t mbs;
85+ int mb_cur_max;
86
87 /* `basefix' is used to avoid `if' tests in the integer scanner */
88 static short basefix[17] =
89 { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
90
91+ NORMALIZE_LOCALE(loc);
92+ mb_cur_max = MB_CUR_MAX_L(loc);
59e0d9fe
A
93 ORIENT(fp, -1);
94
95 nassigned = 0;
96- nconversions = 0;
97 nread = 0;
3d9156a7 98+ va_copy(ap_orig, ap);
59e0d9fe
A
99 for (;;) {
100 c = *fmt++;
3d9156a7
A
101 if (c == 0)
102 return (nassigned);
103- if (isspace(c)) {
104- while ((fp->_r > 0 || __srefill(fp) == 0) && isspace(*fp->_p))
105+ if (isspace_l(c, loc)) {
106+ while ((fp->_r > 0 || __srefill(fp) == 0) && isspace_l(*fp->_p, loc))
107 nread++, fp->_r--, fp->_p++;
108 continue;
109 }
34e8f829
A
110- if (c != '%')
111+ if (c != '%') {
112+ if (fp->_r <= 0 && __srefill(fp))
113+ goto input_failure;
114 goto literal;
115+ }
116 width = 0;
117 flags = 0;
118 /*
1f2f436a 119@@ -167,15 +189,35 @@ __svfscanf(FILE *fp, const char *fmt0, v
34e8f829
A
120 again: c = *fmt++;
121 switch (c) {
122 case '%':
123+ /* Consume leading white space */
124+ for(;;) {
125+ if (fp->_r <= 0 && __srefill(fp))
126+ goto input_failure;
127+ if (!isspace_l(*fp->_p, loc))
128+ break;
129+ nread++;
130+ fp->_r--;
131+ fp->_p++;
132+ }
133 literal:
134- if (fp->_r <= 0 && __srefill(fp))
135- goto input_failure;
136 if (*fp->_p != c)
137 goto match_failure;
138 fp->_r--, fp->_p++;
3d9156a7
A
139 nread++;
140 continue;
141
142+ case '$':
143+ index = width;
144+ if (index < 1 || index > NL_ARGMAX || fmt[-3] != '%') {
145+ goto input_failure;
146+ }
147+ width = 0;
148+ va_end(ap);
149+ va_copy(ap, ap_orig); /* reset to %1$ */
150+ for (; index > 1; index--) {
151+ va_arg(ap, void*);
152+ }
153+ goto again;
154 case '*':
155 flags |= SUPPRESS;
156 goto again;
1f2f436a 157@@ -262,7 +304,7 @@ literal:
3d9156a7
A
158 break;
159
160 case '[':
161- fmt = __sccl(ccltab, fmt);
162+ fmt = __sccl(ccltab, fmt, loc);
163 flags |= NOSKIP;
164 c = CT_CCL;
165 break;
1f2f436a 166@@ -283,27 +325,28 @@ literal:
59e0d9fe
A
167 break;
168
169 case 'n':
170- nconversions++;
1f2f436a
A
171- if (flags & SUPPRESS) /* ??? */
172+ {
173+ void *ptr = va_arg(ap, void *);
174+ if ((ptr == NULL) || (flags & SUPPRESS)) /* ??? */
59e0d9fe 175 continue;
1f2f436a
A
176- if (flags & SHORTSHORT)
177- *va_arg(ap, char *) = nread;
178+ else if (flags & SHORTSHORT)
179+ *(char *)ptr = nread;
180 else if (flags & SHORT)
181- *va_arg(ap, short *) = nread;
182+ *(short *)ptr = nread;
183 else if (flags & LONG)
184- *va_arg(ap, long *) = nread;
185+ *(long *)ptr = nread;
186 else if (flags & LONGLONG)
187- *va_arg(ap, long long *) = nread;
188+ *(long long *)ptr = nread;
189 else if (flags & INTMAXT)
190- *va_arg(ap, intmax_t *) = nread;
191+ *(intmax_t *)ptr = nread;
192 else if (flags & SIZET)
193- *va_arg(ap, size_t *) = nread;
194+ *(size_t *)ptr = nread;
195 else if (flags & PTRDIFFT)
196- *va_arg(ap, ptrdiff_t *) = nread;
197+ *(ptrdiff_t *)ptr = nread;
198 else
199- *va_arg(ap, int *) = nread;
200+ *(int *)ptr = nread;
201 continue;
202-
203+ }
204 default:
205 goto match_failure;
206
207@@ -325,7 +368,7 @@ literal:
3d9156a7
A
208 * that suppress this.
209 */
210 if ((flags & NOSKIP) == 0) {
211- while (isspace(*fp->_p)) {
212+ while (isspace_l(*fp->_p, loc)) {
213 nread++;
214 if (--fp->_r > 0)
215 fp->_p++;
1f2f436a 216@@ -355,7 +398,7 @@ literal:
3d9156a7
A
217 wcp = NULL;
218 n = 0;
219 while (width != 0) {
220- if (n == MB_CUR_MAX) {
221+ if (n == mb_cur_max) {
222 fp->_flags |= __SERR;
223 goto input_failure;
224 }
1f2f436a 225@@ -363,7 +406,7 @@ literal:
3d9156a7
A
226 fp->_p++;
227 fp->_r--;
228 mbs = initial;
229- nconv = mbrtowc(wcp, buf, n, &mbs);
230+ nconv = mbrtowc_l(wcp, buf, n, &mbs, loc);
231 if (nconv == (size_t)-1) {
232 fp->_flags |= __SERR;
233 goto input_failure;
1f2f436a 234@@ -416,7 +459,6 @@ literal:
59e0d9fe
A
235 nread += r;
236 nassigned++;
237 }
238- nconversions++;
239 break;
240
241 case CT_CCL:
1f2f436a 242@@ -435,7 +477,7 @@ literal:
3d9156a7
A
243 n = 0;
244 nchars = 0;
245 while (width != 0) {
246- if (n == MB_CUR_MAX) {
247+ if (n == mb_cur_max) {
248 fp->_flags |= __SERR;
249 goto input_failure;
250 }
1f2f436a 251@@ -443,7 +485,7 @@ literal:
3d9156a7
A
252 fp->_p++;
253 fp->_r--;
254 mbs = initial;
255- nconv = mbrtowc(wcp, buf, n, &mbs);
256+ nconv = mbrtowc_l(wcp, buf, n, &mbs, loc);
257 if (nconv == (size_t)-1) {
258 fp->_flags |= __SERR;
259 goto input_failure;
1f2f436a 260@@ -451,8 +493,8 @@ literal:
3d9156a7
A
261 if (nconv == 0)
262 *wcp = L'\0';
263 if (nconv != (size_t)-2) {
264- if (wctob(*wcp) != EOF &&
265- !ccltab[wctob(*wcp)]) {
266+ if (wctob_l(*wcp, loc) != EOF &&
267+ !ccltab[wctob_l(*wcp, loc)]) {
268 while (n != 0) {
269 n--;
270 __ungetc(buf[n],
1f2f436a 271@@ -520,7 +562,6 @@ literal:
59e0d9fe
A
272 nassigned++;
273 }
274 nread += n;
275- nconversions++;
276 break;
277
278 case CT_STRING:
1f2f436a 279@@ -535,8 +576,8 @@ literal:
3d9156a7
A
280 else
281 wcp = &twc;
282 n = 0;
283- while (!isspace(*fp->_p) && width != 0) {
284- if (n == MB_CUR_MAX) {
224c7076 285+ while (width != 0) {
3d9156a7
A
286+ if (n == mb_cur_max) {
287 fp->_flags |= __SERR;
288 goto input_failure;
289 }
1f2f436a 290@@ -544,7 +585,7 @@ literal:
3d9156a7
A
291 fp->_p++;
292 fp->_r--;
293 mbs = initial;
294- nconv = mbrtowc(wcp, buf, n, &mbs);
295+ nconv = mbrtowc_l(wcp, buf, n, &mbs, loc);
296 if (nconv == (size_t)-1) {
297 fp->_flags |= __SERR;
298 goto input_failure;
1f2f436a 299@@ -552,7 +593,7 @@ literal:
3d9156a7
A
300 if (nconv == 0)
301 *wcp = L'\0';
302 if (nconv != (size_t)-2) {
303- if (iswspace(*wcp)) {
304+ if (iswspace_l(*wcp, loc)) {
305 while (n != 0) {
306 n--;
307 __ungetc(buf[n],
1f2f436a 308@@ -580,7 +621,7 @@ literal:
3d9156a7
A
309 }
310 } else if (flags & SUPPRESS) {
311 n = 0;
312- while (!isspace(*fp->_p)) {
313+ while (!isspace_l(*fp->_p, loc)) {
314 n++, fp->_r--, fp->_p++;
315 if (--width == 0)
316 break;
1f2f436a 317@@ -590,7 +631,7 @@ literal:
3d9156a7
A
318 nread += n;
319 } else {
320 p0 = p = va_arg(ap, char *);
321- while (!isspace(*fp->_p)) {
322+ while (!isspace_l(*fp->_p, loc)) {
323 fp->_r--;
324 *p++ = *fp->_p++;
325 if (--width == 0)
1f2f436a 326@@ -602,7 +643,6 @@ literal:
59e0d9fe
A
327 nread += p - p0;
328 nassigned++;
329 }
330- nconversions++;
331 continue;
332
333 case CT_INT:
1f2f436a 334@@ -733,9 +773,9 @@ literal:
3d9156a7
A
335
336 *p = 0;
337 if ((flags & UNSIGNED) == 0)
338- res = strtoimax(buf, (char **)NULL, base);
339+ res = strtoimax_l(buf, (char **)NULL, base, loc);
340 else
341- res = strtoumax(buf, (char **)NULL, base);
342+ res = strtoumax_l(buf, (char **)NULL, base, loc);
343 if (flags & POINTER)
344 *va_arg(ap, void **) =
345 (void *)(uintptr_t)res;
1f2f436a 346@@ -758,41 +798,46 @@ literal:
59e0d9fe
A
347 nassigned++;
348 }
349 nread += p - buf;
350- nconversions++;
351 break;
352
3d9156a7 353 #ifndef NO_FLOATING_POINT
59e0d9fe
A
354 case CT_FLOAT:
355+ {
356+ char *pbuf;
357 /* scan a floating point number as if by strtod */
358- if (width == 0 || width > sizeof(buf) - 1)
359- width = sizeof(buf) - 1;
360- if ((width = parsefloat(fp, buf, buf + width)) == 0)
224c7076 361+ if ((width = parsefloat(fp, &pbuf, width, loc)) == 0)
59e0d9fe 362 goto match_failure;
59e0d9fe
A
363 if ((flags & SUPPRESS) == 0) {
364 if (flags & LONGDBL) {
365- long double res = strtold(buf, &p);
3d9156a7 366+ long double res = strtold_l(pbuf, &p, loc);
59e0d9fe
A
367 *va_arg(ap, long double *) = res;
368 } else if (flags & LONG) {
369- double res = strtod(buf, &p);
3d9156a7 370+ double res = strtod_l(pbuf, &p, loc);
59e0d9fe
A
371 *va_arg(ap, double *) = res;
372 } else {
373- float res = strtof(buf, &p);
3d9156a7 374+ float res = strtof_l(pbuf, &p, loc);
59e0d9fe
A
375 *va_arg(ap, float *) = res;
376 }
59e0d9fe
A
377 nassigned++;
378 }
379 nread += width;
380- nconversions++;
59e0d9fe
A
381 break;
382+ }
3d9156a7 383 #endif /* !NO_FLOATING_POINT */
59e0d9fe
A
384 }
385 }
386 input_failure:
387- return (nconversions != 0 ? nassigned : EOF);
388+ return (nassigned ? nassigned : EOF);
389 match_failure:
390 return (nassigned);
391 }
59e0d9fe 392
3d9156a7
A
393+int
394+__svfscanf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap)
395+{
396+ return __svfscanf_l(fp, __current_locale(), fmt0, ap);
397+}
398+
399 /*
400 * Fill in the given table from the scanset at the given format
401 * (just after `['). Return a pointer to the character past the
1f2f436a 402@@ -800,9 +845,10 @@ match_failure:
3d9156a7
A
403 * considered part of the scanset.
404 */
405 static const u_char *
406-__sccl(tab, fmt)
407+__sccl(tab, fmt, loc)
408 char *tab;
409 const u_char *fmt;
410+ locale_t loc;
411 {
412 int c, n, v, i;
413
1f2f436a 414@@ -838,6 +884,7 @@ doswitch:
3d9156a7
A
415 return (fmt - 1);
416
417 case '-':
418+ {
419 /*
420 * A scanset of the form
421 * [01+-]
1f2f436a 422@@ -858,8 +905,8 @@ doswitch:
3d9156a7
A
423 */
424 n = *fmt;
425 if (n == ']'
426- || (__collate_load_error ? n < c :
427- __collate_range_cmp (n, c) < 0
428+ || (loc->__collate_load_error ? n < c :
429+ __collate_range_cmp (n, c, loc) < 0
430 )
431 ) {
432 c = '-';
1f2f436a 433@@ -867,14 +914,14 @@ doswitch:
3d9156a7
A
434 }
435 fmt++;
436 /* fill in the range */
437- if (__collate_load_error) {
438+ if (loc->__collate_load_error) {
439 do {
440 tab[++c] = v;
441 } while (c < n);
442 } else {
443 for (i = 0; i < 256; i ++)
444- if ( __collate_range_cmp (c, i) < 0
445- && __collate_range_cmp (i, n) <= 0
446+ if ( __collate_range_cmp (c, i, loc) < 0
447+ && __collate_range_cmp (i, n, loc) <= 0
448 )
449 tab[i] = v;
450 }
1f2f436a 451@@ -894,7 +941,7 @@ doswitch:
3d9156a7
A
452 return (fmt);
453 #endif
454 break;
455-
456+ }
457 case ']': /* end of scanset */
458 return (fmt);
459
1f2f436a 460@@ -907,8 +954,54 @@ doswitch:
34e8f829 461 }
3d9156a7
A
462
463 #ifndef NO_FLOATING_POINT
34e8f829
A
464+/*
465+ * Maintain a per-thread parsefloat buffer, shared by __svfscanf_l and
466+ * __vfwscanf.
467+ */
468+#ifdef BUILDING_VARIANT
469+extern char *__parsefloat_buf(size_t s);
470+#else /* !BUILDING_VARIANT */
471+__private_extern__ char *
472+__parsefloat_buf(size_t s)
473+{
474+ char *b;
475+ static pthread_key_t parsefloat_tsd_key = (pthread_key_t)-1;
476+ static pthread_mutex_t parsefloat_tsd_lock = PTHREAD_MUTEX_INITIALIZER;
477+ static size_t bsiz = 0;
478+
479+ if (parsefloat_tsd_key == (pthread_key_t)-1) {
480+ pthread_mutex_lock(&parsefloat_tsd_lock);
481+ if (parsefloat_tsd_key == (pthread_key_t)-1) {
482+ parsefloat_tsd_key = __LIBC_PTHREAD_KEY_PARSEFLOAT;
483+ pthread_key_init_np(parsefloat_tsd_key, free);
484+ }
485+ pthread_mutex_unlock(&parsefloat_tsd_lock);
486+ }
487+ if ((b = (char *)pthread_getspecific(parsefloat_tsd_key)) == NULL) {
488+ bsiz = s > BUF ? s : BUF;
489+ b = (char *)malloc(bsiz);
490+ if (b == NULL) {
491+ bsiz = 0;
492+ return NULL;
493+ }
494+ pthread_setspecific(parsefloat_tsd_key, b);
495+ return b;
496+ }
497+ if (s > bsiz) {
498+ b = (char *)reallocf(b, s);
499+ pthread_setspecific(parsefloat_tsd_key, b);
500+ if (b == NULL) {
501+ bsiz = 0;
502+ return NULL;
503+ }
504+ bsiz = s;
505+ }
506+ return b;
507+}
508+#endif /* BUILDING_VARIANT */
509+
59e0d9fe
A
510 static int
511-parsefloat(FILE *fp, char *buf, char *end)
3d9156a7 512+parsefloat(FILE *fp, char **buf, size_t width, locale_t loc)
59e0d9fe
A
513 {
514 char *commit, *p;
1f2f436a
A
515 int infnanpos = 0, decptpos = 0;
516@@ -917,9 +1010,18 @@ parsefloat(FILE *fp, char *buf, char *en
517 S_DIGITS, S_DECPT, S_FRAC, S_EXP, S_EXPDIGITS
3d9156a7 518 } state = S_START;
59e0d9fe 519 unsigned char c;
1f2f436a
A
520- const char *decpt = localeconv()->decimal_point;
521+ const char *decpt = localeconv_l(loc)->decimal_point;
59e0d9fe 522 _Bool gotmantdig = 0, ishex = 0;
224c7076 523-
34e8f829 524+ char *b;
224c7076 525+ char *e;
59e0d9fe 526+ size_t s;
224c7076 527+
224c7076 528+ s = (width == 0 ? BUF : (width + 1));
34e8f829
A
529+ if ((b = __parsefloat_buf(s)) == NULL) {
530+ *buf = NULL;
531+ return 0;
59e0d9fe
A
532+ }
533+ e = b + (s - 1);
534 /*
535 * We set commit = p whenever the string we have read so far
536 * constitutes a valid representation of a floating point
1f2f436a 537@@ -929,8 +1031,8 @@ parsefloat(FILE *fp, char *buf, char *en
59e0d9fe
A
538 * always necessary to read at least one character that doesn't
539 * match; thus, we can't short-circuit "infinity" or "nan(...)".
540 */
541- commit = buf - 1;
542- for (p = buf; p < end; ) {
543+ commit = b - 1;
544+ for (p = b; width == 0 || p < e; ) {
545 c = *fp->_p;
546 reswitch:
547 switch (state) {
1f2f436a 548@@ -988,7 +1090,7 @@ reswitch:
3d9156a7
A
549 if (c == ')') {
550 commit = p;
1f2f436a 551 state = S_DONE;
3d9156a7
A
552- } else if (!isalnum(c) && c != '_')
553+ } else if (!isalnum_l(c, loc) && c != '_')
554 goto parsedone;
555 break;
556 }
1f2f436a 557@@ -1006,7 +1108,7 @@ reswitch:
3d9156a7
A
558 goto reswitch;
559 }
560 case S_DIGITS:
1f2f436a
A
561- if ((ishex && isxdigit(c)) || isdigit(c)) {
562+ if ((ishex && isxdigit_l(c, loc)) || isdigit_l(c, loc)) {
3d9156a7 563 gotmantdig = 1;
224c7076 564 commit = p;
1f2f436a
A
565 break;
566@@ -1041,7 +1143,7 @@ reswitch:
3d9156a7
A
567 goto parsedone;
568 else
569 state = S_EXP;
570- } else if ((ishex && isxdigit(c)) || isdigit(c)) {
571+ } else if ((ishex && isxdigit_l(c, loc)) || isdigit_l(c, loc)) {
572 commit = p;
573 gotmantdig = 1;
574 } else
1f2f436a 575@@ -1054,13 +1156,26 @@ reswitch:
3d9156a7
A
576 else
577 goto reswitch;
578 case S_EXPDIGITS:
579- if (isdigit(c))
580+ if (isdigit_l(c, loc))
581 commit = p;
582 else
583 goto parsedone;
34e8f829 584 break;
59e0d9fe 585 default:
34e8f829
A
586- abort();
587+ LIBC_ABORT("unknown state %d", state);
588+ }
59e0d9fe 589+ if (p >= e) {
224c7076
A
590+ ssize_t diff = (p - b);
591+ ssize_t com = (commit - b);
59e0d9fe 592+ s += BUF;
34e8f829 593+ b = __parsefloat_buf(s);
59e0d9fe
A
594+ if (b == NULL) {
595+ *buf = NULL;
596+ return 0;
597+ }
598+ e = b + (s - 1);
599+ p = b + diff;
224c7076 600+ commit = b + com;
34e8f829 601 }
59e0d9fe
A
602 *p++ = c;
603 if (--fp->_r > 0)
1f2f436a 604@@ -1073,6 +1188,7 @@ parsedone:
59e0d9fe
A
605 while (commit < --p)
606 __ungetc(*(u_char *)p, fp);
607 *++commit = '\0';
608- return (commit - buf);
609+ *buf = b;
610+ return (commit - b);
611 }
612 #endif