Test getndelim2.
[gnulib.git] / lib / getndelim2.c
index 46721e7..8930a5b 100644 (file)
@@ -1,13 +1,13 @@
 /* getndelim2 - Read a line from a stream, stopping at one of 2 delimiters,
    with bounded memory allocation.
 
-   Copyright (C) 1993, 1996, 1997, 1998, 2000, 2003, 2004, 2006 Free
+   Copyright (C) 1993, 1996, 1997, 1998, 2000, 2003, 2004, 2006, 2008 Free
    Software Foundation, Inc.
 
-   This program is free software; you can redistribute it and/or modify
+   This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* Originally written by Jan Brittenson, bson@gnu.ai.mit.edu.  */
 
 #if USE_UNLOCKED_IO
 # include "unlocked-io.h"
 #endif
+#if !HAVE_FLOCKFILE
+# undef flockfile
+# define flockfile(x) ((void) 0)
+#endif
+#if !HAVE_FUNLOCKFILE
+# undef funlockfile
+# define funlockfile(x) ((void) 0)
+#endif
 
 #include <limits.h>
 #include <stdint.h>
 
+#ifndef SSIZE_MAX
+# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
+#endif
+
 /* The maximum value that getndelim2 can return without suffering from
    overflow problems, either internally (because of pointer
    subtraction overflow) or due to the API (because of ssize_t).  */
@@ -70,6 +81,8 @@ getndelim2 (char **lineptr, size_t *linesize, size_t offset, size_t nmax,
   if (nbytes_avail == 0 && nmax <= size)
     goto done;
 
+  flockfile (stream);
+
   for (;;)
     {
       /* Here always ptr + size == read_pos + nbytes_avail.  */
@@ -92,14 +105,14 @@ getndelim2 (char **lineptr, size_t *linesize, size_t offset, size_t nmax,
            {
              size_t newsizemax = offset + GETNDELIM2_MAXIMUM + 1;
              if (size == newsizemax)
-               goto done;
+               goto unlock_done;
              newsize = newsizemax;
            }
 
          nbytes_avail = newsize - (read_pos - ptr);
          newptr = realloc (ptr, newsize);
          if (!newptr)
-           goto done;
+           goto unlock_done;
          ptr = newptr;
          size = newsize;
          read_pos = size - nbytes_avail + ptr;
@@ -110,7 +123,7 @@ getndelim2 (char **lineptr, size_t *linesize, size_t offset, size_t nmax,
        {
          /* Return partial line, if any.  */
          if (read_pos == ptr)
-           goto done;
+           goto unlock_done;
          else
            break;
        }
@@ -132,8 +145,11 @@ getndelim2 (char **lineptr, size_t *linesize, size_t offset, size_t nmax,
 
   bytes_stored = read_pos - (ptr + offset);
 
+ unlock_done:
+  funlockfile (stream);
+
  done:
   *lineptr = ptr;
   *linesize = size;
-  return bytes_stored;
+  return bytes_stored ? bytes_stored : -1;
 }