Ticket #43804: patch-getdelim.c.diff

File patch-getdelim.c.diff, 2.9 KB (added by harciga, 10 years ago)
  • new file getdelim.c

    - +  
     1/* getdelim.c --- Implementation of replacement getdelim function.
     2   Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005 Free
     3   Software Foundation, Inc.
     4
     5   This program is free software; you can redistribute it and/or
     6   modify it under the terms of the GNU General Public License as
     7   published by the Free Software Foundation; either version 2, or (at
     8   your option) any later version.
     9
     10   This program is distributed in the hope that it will be useful, but
     11   WITHOUT ANY WARRANTY; without even the implied warranty of
     12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13   General Public License for more details.
     14
     15   You should have received a copy of the GNU General Public License
     16   along with this program; if not, write to the Free Software
     17   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
     18   02110-1301, USA.  */
     19
     20/* Ported from glibc by Simon Josefsson. */
     21
     22#ifdef HAVE_CONFIG_H
     23# include <config.h>
     24#endif
     25
     26#include <stdlib.h>
     27#include <errno.h>
     28
     29#include "getdelim.h"
     30
     31#if !HAVE_FLOCKFILE
     32# undef flockfile
     33# define flockfile(x) ((void) 0)
     34#endif
     35#if !HAVE_FUNLOCKFILE
     36# undef funlockfile
     37# define funlockfile(x) ((void) 0)
     38#endif
     39
     40/* Read up to (and including) a DELIMITER from FP into *LINEPTR (and
     41   NUL-terminate it).  *LINEPTR is a pointer returned from malloc (or
     42   NULL), pointing to *N characters of space.  It is realloc'ed as
     43   necessary.  Returns the number of characters read (not including
     44   the null terminator), or -1 on error or EOF.  */
     45
     46ssize_t
     47getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp)
     48{
     49  int result = 0;
     50  ssize_t cur_len = 0;
     51  ssize_t len;
     52
     53  if (lineptr == NULL || n == NULL || fp == NULL)
     54    {
     55      errno = EINVAL;
     56      return -1;
     57    }
     58
     59  flockfile (fp);
     60
     61  if (*lineptr == NULL || *n == 0)
     62    {
     63      *n = 120;
     64      *lineptr = (char *) malloc (*n);
     65      if (*lineptr == NULL)
     66        {
     67          result = -1;
     68          goto unlock_return;
     69        }
     70    }
     71
     72  for (;;)
     73    {
     74      char *t;
     75      int i;
     76
     77      i = getc (fp);
     78      if (i == EOF)
     79      {
     80        result = -1;
     81        break;
     82      }
     83
     84      /* Make enough space for len+1 (for final NUL) bytes.  */
     85      if (cur_len + 1 >= *n)
     86        {
     87          size_t needed = 2 * (cur_len + 1) + 1;   /* Be generous. */
     88          char *new_lineptr;
     89
     90          if (needed < cur_len)
     91            {
     92              result = -1;
     93              goto unlock_return;
     94            }
     95
     96          new_lineptr = (char *) realloc (*lineptr, needed);
     97          if (new_lineptr == NULL)
     98            {
     99              result = -1;
     100              goto unlock_return;
     101            }
     102
     103          *lineptr = new_lineptr;
     104          *n = needed;
     105        }
     106
     107      (*lineptr)[cur_len] = i;
     108      cur_len++;
     109
     110      if (i == delimiter)
     111        break;
     112    }
     113  (*lineptr)[cur_len] = '\0';
     114  result = cur_len ? cur_len : result;
     115
     116 unlock_return:
     117  funlockfile (fp);
     118  return result;
     119}