Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libc/stdio Remove __getdelim and just use getdelim.



details:   https://anonhg.NetBSD.org/src/rev/f09bade568db
branches:  trunk
changeset: 749487:f09bade568db
user:      roy <roy%NetBSD.org@localhost>
date:      Tue Dec 01 00:03:53 2009 +0000

description:
Remove __getdelim and just use getdelim.
fgetstr now works with strings up to SSIZE_MAX as a result, but may
reallocate buffers needlessly just like it used to when the buffer size
exceeds INT_MAX.
fgetstr converts errno EOVERFLOW to EINVAL on getdelim error.

diffstat:

 lib/libc/stdio/fgetstr.c  |  30 +++++++++++++++++-------------
 lib/libc/stdio/getdelim.c |  42 +++++++++++++-----------------------------
 lib/libc/stdio/local.h    |   4 +---
 3 files changed, 31 insertions(+), 45 deletions(-)

diffs (171 lines):

diff -r 825d24e94119 -r f09bade568db lib/libc/stdio/fgetstr.c
--- a/lib/libc/stdio/fgetstr.c  Mon Nov 30 23:23:29 2009 +0000
+++ b/lib/libc/stdio/fgetstr.c  Tue Dec 01 00:03:53 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fgetstr.c,v 1.8 2009/10/15 00:36:24 roy Exp $      */
+/* $NetBSD: fgetstr.c,v 1.9 2009/12/01 00:03:53 roy Exp $      */
 
 /*
  * Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: fgetstr.c,v 1.8 2009/10/15 00:36:24 roy Exp $");
+__RCSID("$NetBSD: fgetstr.c,v 1.9 2009/12/01 00:03:53 roy Exp $");
 
 #include "namespace.h"
 
@@ -51,24 +51,28 @@
 {
        char *p;
        size_t size;
+       ssize_t n;
 
        _DIAGASSERT(fp != NULL);
        _DIAGASSERT(lenp != NULL);
 
        p = (char *)fp->_lb._base;
        size = fp->_lb._size;
-       *lenp = __getdelim(&p, &size, sep, fp);
+       n = getdelim(&p, &size, sep, fp);
        fp->_lb._base = (unsigned char *)p;
-       /* The struct size variable is only an int ..... */
-       if (size > INT_MAX) {
+       /* The struct size variable is only an int .....
+        * This still works when exceeded, but the buffer could be
+        * realloced needlessly. */
+       if (size > INT_MAX)
                fp->_lb._size = INT_MAX;
-               errno = EOVERFLOW;
-               goto error;
+       else
+               fp->_lb._size = (int)size;
+       if (n == -1) {
+               *lenp = 0;
+               if (errno == EOVERFLOW) /* fixup errno */
+                       errno = EINVAL;
+               return NULL;
        }
-       fp->_lb._size = (int)size;
-       if (*lenp != 0 && *lenp < SIZE_MAX - 1)
-               return p;
-error:
-       *lenp = 0;
-       return NULL;
+       *lenp = n;
+       return p;
 }
diff -r 825d24e94119 -r f09bade568db lib/libc/stdio/getdelim.c
--- a/lib/libc/stdio/getdelim.c Mon Nov 30 23:23:29 2009 +0000
+++ b/lib/libc/stdio/getdelim.c Tue Dec 01 00:03:53 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: getdelim.c,v 1.7 2009/10/25 20:44:13 christos Exp $ */
+/* $NetBSD: getdelim.c,v 1.8 2009/12/01 00:03:53 roy Exp $ */
 
 /*
  * Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: getdelim.c,v 1.7 2009/10/25 20:44:13 christos Exp $");
+__RCSID("$NetBSD: getdelim.c,v 1.8 2009/12/01 00:03:53 roy Exp $");
 
 #include "namespace.h"
 
@@ -49,11 +49,8 @@
  * without the need for a realloc. */
 #define MINBUF 128
 
-/* This private function allows strings of upto SIZE_MAX - 2
- * and returns 0 on EOF, both of which are disallowed by POSIX.
- * Maybe this should be named fgetdelim and proposed to the OpenGroup....*/
 ssize_t
-__getdelim(char **__restrict buf, size_t *__restrict buflen,
+getdelim(char **__restrict buf, size_t *__restrict buflen,
     int sep, FILE *__restrict fp)
 {
        unsigned char *p;
@@ -74,11 +71,12 @@
        FLOCKFILE(fp);
        _SET_ORIENTATION(fp, -1);
        off = 0;
-       for (;;) {
+       do {
                /* If the input buffer is empty, refill it */
                if (fp->_r <= 0 && __srefill(fp)) {
                        if (__sferror(fp))
                                goto error;
+                       /* No error, so EOF. */
                        break;
                }
 
@@ -91,7 +89,7 @@
 
                newlen = off + len + 1;
                /* Ensure we can handle it */
-               if (newlen < off || newlen > SIZE_MAX - 2) {
+               if (newlen < off || newlen > (size_t)SSIZE_MAX + 1) {
                        errno = EOVERFLOW;
                        goto error;
                }
@@ -124,33 +122,19 @@
                fp->_r -= (int)len;
                fp->_p += (int)len;
                off += len;
-               if (p != NULL)
-                       break;
-       }
+       } while (p == NULL);
        FUNLOCKFILE(fp);
+
+       /* POSIX demands we return -1 on EOF. */
+       if (off == 0) 
+               return -1;
+
        if (*buf != NULL)
                *(*buf + off) = '\0';
        return off;
 
 error:
+       fp->_flags |= __SERR;
        FUNLOCKFILE(fp);
        return -1;
 }
-
-ssize_t
-getdelim(char **__restrict buf, size_t *__restrict buflen,
-    int sep, FILE *__restrict fp)
-{
-       ssize_t len;
-
-       len = __getdelim(buf, buflen, sep, fp);
-       if (len == 0) {
-               /* POSIX requires that we return -1 on EOF */
-               return -1;
-       } else if (len < -1) {
-               /* POSIX requires no string larger than SSIZE_MAX */
-               errno = EOVERFLOW;
-               return -1;
-       }
-       return len;
-}
diff -r 825d24e94119 -r f09bade568db lib/libc/stdio/local.h
--- a/lib/libc/stdio/local.h    Mon Nov 30 23:23:29 2009 +0000
+++ b/lib/libc/stdio/local.h    Tue Dec 01 00:03:53 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: local.h,v 1.21 2009/09/24 20:38:53 roy Exp $   */
+/*     $NetBSD: local.h,v 1.22 2009/12/01 00:03:53 roy Exp $   */
 
 /*-
  * Copyright (c) 1990, 1993
@@ -75,8 +75,6 @@
 extern wint_t  __fgetwc_unlock __P((FILE *));
 extern wint_t  __fputwc_unlock __P((wchar_t, FILE *));
 
-extern ssize_t __getdelim __P((char ** __restrict, size_t * __restrict, int,
-    FILE * __restrict));
 extern char    *__fgetstr __P((FILE * __restrict, size_t * __restrict, int));
 extern int      __vfwprintf_unlocked __P((FILE *, const wchar_t *,
     _BSD_VA_LIST_));



Home | Main Index | Thread Index | Old Index